จะพิมพ์ XML จากบรรทัดคำสั่งได้อย่างไร


528

ที่เกี่ยวข้อง: ฉันจะพิมพ์ JSON in (unix) shell script ได้อย่างไร

มีเชลล์สคริปต์ (unix) เพื่อจัดรูปแบบ XML ในรูปแบบที่มนุษย์อ่านหรือไม่

โดยพื้นฐานแล้วฉันต้องการให้มันแปลงค่าต่อไปนี้:

<root><foo a="b">lorem</foo><bar value="ipsum" /></root>

... เป็นอะไรเช่นนี้:

<root>
    <foo a="b">lorem</foo>
    <bar value="ipsum" />
</root>

1
เพื่อxmllintให้สามารถใช้งานได้กับระบบ Debian คุณจะต้องติดตั้งแพ็กเกจlibxml2-utils( libxml2ไม่มีเครื่องมือนี้อย่างน้อยต้องไม่มีใน Debian 5.0 "Lenny" และ 6.0 "Squeeze")
twonkeys

คำตอบ:


909

libxml2-utils

ยูทิลิตี้นี้มาพร้อมกับlibxml2-utils:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xmllint --format -

ของ Perl XML::Twig

คำสั่งนี้มาพร้อมกับXML :: Twig โมดูลบางครั้งxml-twig-toolsแพ็คเกจ:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xml_pp

xmlstarlet

คำสั่งนี้มาพร้อมกับxmlstarlet:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xmlstarlet format --indent-tab

tidy

ตรวจสอบtidyแพ็คเกจ:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    tidy -xml -i -

หลาม

Python xml.dom.minidomสามารถจัดรูปแบบ XML (ทั้ง python2 และ python3):

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    python -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print(xml.dom.minidom.parseString(s).toprettyxml())'

saxon-lint

คุณต้องการsaxon-lint:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    saxon-lint --indent --xpath '/' -

saxon-HE

คุณต้องการsaxon-HE:

 echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    java -cp /usr/share/java/saxon/saxon9he.jar net.sf.saxon.Query \
    -s:- -qs:/ '!indent=yes'

ดีคำตอบที่รวดเร็ว ตัวเลือกแรกดูเหมือนว่าจะแพร่หลายมากขึ้นในการติดตั้ง * nix ที่ทันสมัย ประเด็นย่อย; แต่จะสามารถเรียกใช้โดยไม่ทำงานผ่านไฟล์ระดับกลางได้หรือไม่ คือecho '<xml .. />' | xmllint --some-read-from-stdn-option?
svidgen

แพคเกจอยู่libxml2-utilsในอูบุนตูที่สวยงามของฉัน
franzlorenzon

1
โปรดทราบว่า "cat data.xml | xmllint --format - | tee data.xml" ไม่ทำงาน ในระบบของฉันบางครั้งมันใช้งานได้กับไฟล์ขนาดเล็ก แต่มักจะตัดทอนไฟล์ขนาดใหญ่เสมอ หากคุณต้องการทำอะไรในสถานที่จริงๆอ่านbackreference.org/2011/01/29/in-place-editing-of-files
user1346466

1
ในการแก้ปัญหาUnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 805: ordinal not in range(128)ในเวอร์ชั่นไพ ธ อนคุณต้องการนิยามPYTHONIOENCODING="UTF-8":cat some.xml | PYTHONIOENCODING="UTF-8" python -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print xml.dom.minidom.parseString(s).toprettyxml()' > pretty.xml
FelikZ

1
โปรดทราบว่าเรียบร้อยสามารถจัดรูปแบบ xml โดยไม่มีองค์ประกอบรูต สิ่งนี้มีประโยชน์ในการฟอร์แมตผ่านไพพ์ส่วน xml (เช่นแยกจากบันทึก) echo '<x></x><y></y>' | tidy -xml -iq
Marinos

157

xmllint --format yourxmlfile.xml

xmllintเป็นเครื่องมือบรรทัดคำสั่ง XML และรวมอยู่ในlibxml2( http://xmlsoft.org/ )

================================================

หมายเหตุ: หากคุณยังไม่ได้libxml2ติดตั้งคุณสามารถติดตั้งได้โดยทำดังต่อไปนี้:

CentOS

cd /tmp
wget ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz
tar xzf libxml2-2.8.0.tar.gz
cd libxml2-2.8.0/
./configure
make
sudo make install
cd

อูบุนตู

sudo apt-get install libxml2-utils

Cygwin

apt-cyg install libxml2

MacOS

ในการติดตั้งสิ่งนี้บน MacOS ด้วย Homebrew เพียงทำ: brew install libxml2

Git

นอกจากนี้ยังมีใน Git หากคุณต้องการรหัส: git clone git://git.gnome.org/libxml2


4
คำตอบของ sputnick มีข้อมูลนี้ แต่คำตอบของ crmpicco เป็นคำตอบที่มีประโยชน์ที่สุดสำหรับคำถามทั่วไปเกี่ยวกับวิธีการพิมพ์ XML
Seth Difley

2
เราสามารถเขียนเอาท์พุท xml ที่จัดรูปแบบนั้นไปยังไฟล์ xml อื่น ๆ และใช้สิ่งนั้น .. เช่น xmllint - ฟอร์แมต yourxmlfile.xml >> new-file.xml
LearnToLive

2
บน Ubuntu 16.04 คุณสามารถใช้สิ่งต่อไปนี้:sudo apt-get install libxml2-utils
Melle

ใช้ได้กับ Windows เช่นกัน gitสำหรับ Windows ดาวน์โหลดxmllintแม้จะติดตั้งรุ่นล่าสุดของ ตัวอย่าง:"C:\Program Files\Git\usr\bin\xmllint.exe" --format QCScaper.test@borland.com.cds.xml > QCScaper.test@borland.com.pretty-printed.cds.xml
Jeroen Wiert Pluimers

41

คุณสามารถใช้ระเบียบซึ่งอาจจะต้องติดตั้งก่อน (เช่นบน Ubuntu: sudo apt-get install tidy)

สำหรับสิ่งนี้คุณจะออกสิ่งต่อไปนี้:

tidy -xml -i your-file.xml > output.xml

หมายเหตุ: มีแฟล็กความสามารถในการอ่านเพิ่มเติมจำนวนมาก แต่ลักษณะการทำงานของการห่อคำนั้นค่อนข้างน่ารำคาญที่จะทำให้ยุ่งเหยิงเล็กน้อย ( http://tidy.sourceforge.net/docs/quickref.html )


1
มีประโยชน์เพราะฉันไม่สามารถรับ xmllint เพื่อเพิ่ม linebreaks ไปยังไฟล์ xml บรรทัดเดียว ขอบคุณ!
xlttj

tidyทำงานได้ดีสำหรับฉันเช่นกัน hxnormalizeสิ่งนี้ต่างจากการปิด<body>แท็กจริง
Sridhar Sarnobat

9
BTW tidy --indent yes --indent-spaces 4 --indent-attributes yes --wrap-attributes yes --input-xml yes --output-xml yes < InFile.xml > OutFile.xmlที่นี่เป็นตัวเลือกบางอย่างที่ฉันได้พบว่ามีประโยชน์:
Victor Yarema

2
เคล็ดลับที่ยอดเยี่ยม @VictorYarema ฉันรวมมันด้วยการเพิ่มและเพิ่มลงใน. bashrc ของฉัน: alias prettyxml='tidy --indent yes --indent-spaces 4 --indent-attributes yes --wrap-attributes yes --input-xml yes --output-xml yes | pygmentize -l xml' และจากนั้นสามารถcurl url | prettyxml
Net Wolf

13

คุณไม่ได้พูดถึงไฟล์ดังนั้นฉันถือว่าคุณต้องการให้สตริง XML เป็นอินพุตมาตรฐานในบรรทัดคำสั่ง ในกรณีดังกล่าวให้ทำดังนี้

$ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | xmllint --format -

12

โดยไม่ต้องติดตั้งอะไรบน macOS / Unix ส่วนใหญ่

ใช้ tidy

cat filename.xml | tidy -xml -iq

การเปลี่ยนเส้นทางการดูไฟล์ด้วย cat เพื่อให้เป็นระเบียบระบุชนิดของไฟล์ของ xml และเยื้องในขณะที่เอาต์พุตเงียบจะหยุดเอาต์พุตข้อผิดพลาด JSON -jsonยังทำงานร่วมกับ


1
คุณไม่ต้องการcatขั้นตอน: tidy -xml -iq filename.xml. นอกจากนี้คุณยังสามารถทำtidy -xml -iq filename.xmlโดยใช้-mตัวเลือกในการปรับเปลี่ยนไฟล์ต้นฉบับ ...
janniks

10

xmllint สนับสนุนการจัดรูปแบบในสถานที่ :

for f in *.xml; do xmllint -o $f --format $f; done

ตามที่ Daniel Veillard ได้เขียนไว้:

ฉันคิดว่า xmllint -o tst.xml --format tst.xml ควรจะปลอดภัยเพราะ parser จะโหลดข้อมูลเข้าสู่ต้นไม้อย่างเต็มที่ก่อนที่จะเปิดเอาต์พุตเพื่อทำให้เป็นอันดับ

ระดับการเยื้องถูกควบคุมโดยXMLLINT_INDENTตัวแปรสภาพแวดล้อมซึ่งโดยค่าเริ่มต้น 2 ช่องว่าง ตัวอย่างวิธีเปลี่ยนการเยื้องเป็น 4 ช่องว่าง:

XMLLINT_INDENT='    '  xmllint -o out.xml --format in.xml

คุณอาจไม่มี--recoverทางเลือกเมื่อเอกสาร XML ของคุณเสีย หรือลองใช้โปรแกรมแยกวิเคราะห์ HTML แบบอ่อนที่มีเอาต์พุต XML ที่เข้มงวด:

xmllint --html --xmlout <in.xml >out.xml

--nsclean, --nonet, --nocdata, --noblanksฯลฯ อาจจะมีประโยชน์ อ่าน man page

apt-get install libxml2-utils
apt-cyg install libxml2
brew install libxml2

2

สิ่งนี้ทำให้ฉันตลอดไปเพื่อค้นหาสิ่งที่ทำงานบน mac นี่คือสิ่งที่ทำงานสำหรับฉัน:

brew install xmlformat
cat unformatted.html | xmlformat

1
คำตอบของฉันทำงานบน mac
jasonleonhard

1

ฉันต้องการเพิ่มโซลูชันทุบตีบริสุทธิ์เนื่องจากไม่ใช่ 'ที่' ยากที่จะทำด้วยมือและบางครั้งคุณไม่ต้องการติดตั้งเครื่องมือพิเศษเพื่อทำงาน

#!/bin/bash

declare -i currentIndent=0
declare -i nextIncrement=0
while read -r line ; do
  currentIndent+=$nextIncrement
  nextIncrement=0
  if [[ "$line" == "</"* ]]; then # line contains a closer, just decrease the indent
    currentIndent+=-1
  else
    dirtyStartTag="${line%%>*}"
    dirtyTagName="${dirtyStartTag%% *}"
    tagName="${dirtyTagName//</}"
    # increase indent unless line contains closing tag or closes itself
    if [[ ! "$line" =~ "</$tagName>" && ! "$line" == *"/>"  ]]; then
      nextIncrement+=1
    fi
  fi

  # print with indent
  printf "%*s%s" $(( $currentIndent * 2 )) # print spaces for the indent count
  echo $line
done <<< "$(cat - | sed 's/></>\n</g')" # separate >< with a newline

วางไว้ในไฟล์สคริปต์และไพพ์ใน xml สิ่งนี้ถือว่า xml อยู่ในหนึ่งบรรทัดและไม่มีที่ว่างเพิ่มเติม หนึ่งสามารถเพิ่มพิเศษบางอย่าง\s*เพื่อ regexes เพื่อแก้ไข

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.