XMLStarlet是一组命令行实用程序(工具),可以使用简单的shell命令集来转换,查询,验证和编辑XML文档和文件,就像使用UNIX grep,sed对纯文本文件一样。 awk,diff,patch,join等命令。
所以,我将其作为输入文件 temp.html: 所以,我将其作为输入文件,temp.html: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html><body> <div id="ext-comp-1725" class="x-window FM-Msg-cls utility-window q-fileExplorer-window q-window show-header-line x-window-noborder x-window-plain x-resizable-pinned q-modal-window" style="position: absolute; z-index: 8020; visibility: visible; left: 188px; top: 62px; width: 900px; display: block;"> <div class="x-window-tl"><div class="x-window-tr"><div class="x-window-tc"><div class="x-window-header x-window-header-noborder x-unselectable x-window-draggable" id="ext-gen1530" style="user-select: none;"> <div class="x-tool-ct x-tool x-tool-bg" id="ext-gen1536"><div class="x-tool x-tool-icon x-tool-close"> </div></div> <span class="x-window-header-text" id="ext-gen1541">Hello</span> </div></div></div></div> </body></html> 我希望我可以通过使用 xmlstarlet: 来漂亮地打印和缩进标签 $ xmlstarlet fo --html --recover --indent-spaces 2 --omit-decl temp.html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <body> <div id="ext-comp-1725" class="x-window FM-Msg-cls utility-window q-fileExplorer-window q-window show-header-line x-window-noborder x-window-plain x-resizable-pinned q-modal-window" style="position: absolute; z-index: 8020; visibility: visible; left: 188px; top: 62px; width: 900px; display: block;"> <div class="x-window-tl"><div class="x-window-tr"><div class="x-window-tc"><div class="x-window-header x-window-header-noborder x-unselectable x-window-draggable" id="ext-gen1530" style="user-select: none;"> <div class="x-tool-ct x-tool x-tool-bg" id="ext-gen1536"><div class="x-tool x-tool-icon x-tool-close">├é┬á</div></div> <span class="x-window-header-text" id="ext-gen1541">Hello</span> </div></div></div></div> </div></body> </html> ...但是,从上面的命令输出中可以明显看出,它只缩进一些标签(例如,它拆分了 <html><body> 并正确缩进了这些标签) - 但在其他标签上失败了(例如,它将 </div></div></div></div> 保留在一行中) ). 是否可以说服/设置xmlstarlet拆分并缩进所有标签,每行一个标签,并进行适当的缩进? $ xmlstarlet --version srcinfo-cache compiled against libxml2 2.9.10, linked with 21209 compiled against libxslt 1.1.34, linked with 10142 好吧,看来 tidy 在这里可以工作(通过 命令行 HTML 漂亮打印机:使混乱的 HTML 可读找到它): $ tidy --version HTML Tidy for Windows version 5.8.0 $ tidy -indent -wrap 160 -ashtml -utf8 temp.html line 3 column 1 - Warning: missing </div> line 2 column 7 - Warning: inserting missing 'title' element Info: Doctype given is "-//W3C//DTD HTML 4.0 Transitional//EN" Info: Document content looks like HTML 4.01 Strict Tidy found 2 warnings and 0 errors! <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <meta name="generator" content="HTML Tidy for HTML5 for Windows version 5.8.0"> <title></title> </head> <body> <div id="ext-comp-1725" class= "x-window FM-Msg-cls utility-window q-fileExplorer-window q-window show-header-line x-window-noborder x-window-plain x-resizable-pinned q-modal-window" style="position: absolute; z-index: 8020; visibility: visible; left: 188px; top: 62px; width: 900px; display: block;"> <div class="x-window-tl"> <div class="x-window-tr"> <div class="x-window-tc"> <div class="x-window-header x-window-header-noborder x-unselectable x-window-draggable" id="ext-gen1530" style="user-select: none;"> <div class="x-tool-ct x-tool x-tool-bg" id="ext-gen1536"> <div class="x-tool x-tool-icon x-tool-close"> </div> </div><span class="x-window-header-text" id="ext-gen1541">Hello</span> </div> </div> </div> </div> </div> </body> </html> About HTML Tidy: https://github.com/htacg/tidy-html5 Bug reports and comments: https://github.com/htacg/tidy-html5/issues Official mailing list: https://lists.w3.org/Archives/Public/public-htacg/ Latest HTML specification: http://dev.w3.org/html5/spec-author-view/ Validate your HTML documents: http://validator.w3.org/nu/ Lobby your company to join the W3C: http://www.w3.org/Consortium Do you speak a language other than English, or a different variant of English? Consider helping us to localize HTML Tidy. For details please see https://github.com/htacg/tidy-html5/blob/master/README/LOCALIZE.md
我没有获得外部 DTD(同一文件夹中的本地文件)来使用相对或绝对路径。它不会扩展变量并在 Firefox 和 xmlstarlet 中给出错误。
如何? xmlstarlet 通过 id 提取 HTML 数据
我有一个简单的任务,让我把头发拉出来,我确信我已经非常接近了。 这是我的 xhtml 文件: 我有一个简单的任务,需要我把头发拔出来,我确信我已经非常接近了。 这是我的 xhtml 文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Test Page</title> </head> <body> <p> test </p> <table id="test_table"> <tr><td>test</td><td>test</td></tr> <tr><th>mo test</th></tr> </table> </body> </html> ...并且 xmlstarlet 喜欢它: $ xmlstarlet.exe el -v test.xhtml html[@xmlns='http://www.w3.org/1999/xhtml'] html/head html/head/title html/body html/body/p html/body/table[@id='test_table'] html/body/table/tr html/body/table/tr/td html/body/table/tr/td html/body/table/tr html/body/table/tr/th 我需要做的是提取表格标签中的数据,最好没有 HTML。 其背景是我正在编写一个测试集,其中调用网页然后写入文件。 该测试要求我验证表数据,但如果页面上的其他内容发生变化,则允许测试成功。 另外,我不会提前知道表格将有多少列或行,它可能会根据数据而变化。 但是当我尝试时: $ xmlstarlet.exe sel -t -c "/html/body/table[@id='test_table']" test.xhtml Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd None of the XPaths matched; to match a node in the default namespace use '_' as the prefix (see section 5.1 in the manual). For instance, use /_:node instead of /node 不同的测试需要不同的 id,但它们都有唯一的 id 值。 所以,给定 xhthml 中的任何“id”,我需要它的数据。 提前致谢。 html数据有一个默认命名空间,您必须在xmlstarlet命令中声明: xmlstarlet sel \ -N n="http://www.w3.org/1999/xhtml" \ -t \ -c "/n:html/n:body/n:table[@id='test_table']/descendant::*/text()" \ htmlfile 2>/dev/null 找到 <table> 元素后,我使用 descendant::*/text() 提取它的所有文本元素,并使用 2>/dev/null 跳过警告: Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 它产生: testtestmo test 更新:我不知道,但正如错误消息所示,当命名空间是默认命名空间时,无需声明命名空间,所以这也有效: xmlstarlet sel \ -t \ -c "/_:html/_:body/_:table[@id='test_table']/descendant::*/text()" \ htmlfile 2>/dev/null 正如中提到的 http://xmlstar.sourceforge.net/doc/UG/ch05.html 使用时常见问题 -N x="http://www.w3.org/1999/xhtml" \ 您还必须为节点选择添加前缀 x: 例如 xmlstarlet sel \ -N x="http://www.w3.org/1999/xhtml" \ -t \ -m "//x:pre" \ -v . somehtml.html 将选择所有前置节点 你可以试试 xmlstarlet ed --inplace -u "html/body/table[@id='your_tabl e_id']/tr[@id='row_id']/td[@id='data_id']" -v NEW_VALUE_TO_BE_CHANGED HTMLFILE_NAME 2>/dev/null
我有与此类似的 XML: 11111 我有与此类似的 XML: <orders> <orderCompleteRequestType> <Head> <Aufnr>11111</Aufnr> </Head> <Register> <Id>180</Id> <value1>11</value1> <value2>22</value2> </Register> <Register> <Id>181</Id> <value1>3</value1> <value2>43</value2> </Register> <Register> <Id>160</Id> <value1>5</value1> <value2>25</value2> </Register> </orderCompleteRequestType> <orderCompleteRequestType> <Head> <Aufnr>22222</Aufnr> </Head> <Register> <Id>280</Id> <value1>1</value1> <value2>12</value2> </Register> <Register> <Id>160</Id> <value1>12</value1> <value2>7</value2> </Register> <Register> <Id>281</Id> <value1>94</value1> <value2>22</value2> </Register> </orderCompleteRequestType> </orders> 我想从每个“orderCompleteRequestType”结构中选择 CSV 格式的一些值: 头/奥夫恩 注册/ID 寄存器/值1 寄存器/值2 使用以下命令行时: xmlstarlet sel -T -t -m "/orders/orderCompleteRequestType" -v "Head/Aufnr" -o ";" -v "Register/Id" -o ";" -v "Register/value1" -o ";" -v "Register/value2" -n -n test.xml 我得到: 11111;180 181 160;11 3 5;22 43 25 22222;280 160 281;1 12 94;12 7 22 所以,首先是 Register/Id 节点的所有值,接下来是所有 Register/value1,最后是所有 Register/value2,但我期望的是这样的: 11111;180;11;22 11111;181;3;43 11111;160;5;25 22222;280;1;12 22222;160;12;7 22222;281;94;22 任何人都可以帮助我,因为我的大脑拒绝工作...... 不要匹配 orderCompleteRequestType,而是考虑匹配 Register... xmlstarlet sel -T -t -m "/orders/orderCompleteRequestType/Register" -v "concat(../Head/Aufnr,';',Id,';',value1,';',value2)" -n test.xml 输出... 11111;180;11;22 11111;181;3;43 11111;160;5;25 22222;280;1;12 22222;160;12;7 22222;281;94;22 每个orderCompleteRequestType之间没有额外的换行符,但这也许没什么大不了的?如果是,那么编写 XSLT 并使用 xmlstarlet 调用它可能会更容易。
xmlstarlet - 需要根据另一个属性的值有选择地替换属性值
只是想知道是否有人可以帮助我。 我目前正在构建 pfsense 防火墙,它使用 VPN 连接来保护流量。 VPN 提供商确实提供了端口转发机制,但是
我正在使用 XMLStarlet 为我的应用程序快速部署 cmd (Windows) 脚本,并且我正在更改配置 xml 文件。 整个节点/属性的操作非常完美,但我需要
我正在尝试使用 sed 命令更改 XML 中的标签值。我也使用了 xmlstarlet,但由于 CDATA 标记而没有帮助。下面是标签。 但 xmlstarlet 将 < to < and > 更改为...
我是新使用 xmlstarlet。 我想知道如何使用 xmlstarlet 更改 xml 节点的值。 我尝试了一些东西。 xmlstarlet ed --inplace -u '/file_input/uri' 'string("s3://my_source"...
我想使用xmlstarlet来选择一个巨大的.xml文件的一些记录。我的问题是,我需要输出是有效的 XML。 最小的例子: 使用 xmlstarlet sel -t -c "//记录[@type='Typ...
如果在任何标签中找到 epm_default_cloud_admin,我需要删除下面的整个 cellNote 元素,使用 xmlstarlet 尝试不同的操作,但不会发生这种情况,你能帮忙吗? 如果在任何标签中找到 cellNote,我需要删除下面的整个 epm_default_cloud_admin 元素,使用 xmlstarlet 尝试不同的操作,但不会发生这种情况,你能帮忙吗? <cell> <cellNote> <DIM1>Actual</DIM1> <author>epm_default_cloud_admin</author> <modified>2016-11-16 08:28:38.0</modified> <title/> </cellNote> <cellNote> <DIM1>Actual</DIM1> <contents>Variance in meals is due to Annual Sales Conference</contents> <author>Frank</author> <modified>2016-12-23 20:10:13.0</modified> <title/> </cellNote> <cell> 我在下面尝试过的一些事情: xmlstarlet ed -a "/cell/cellNote" --type elem -n string -v "epm_default_cloud_admin" xmlstarlet ed -d '/cell/cellNote/author[. = 'epm_default_cloud_admin']' 首先,要处理有效的 xml - 确保 cell 标签同时具有开始和结束标签(您的输入同时包含开始 <cell>)。 xmlstarlet解决方案: xmlstarlet ed -d "//cellNote[*[contains(text(),'epm_default_cloud_admin')]]" input.xml 输出: <?xml version="1.0"?> <cell> <cellNote> <DIM1>Actual</DIM1> <contents>Variance in meals is due to Annual Sales Conference</contents> <author>Frank</author> <modified>2016-12-23 20:10:13.0</modified> <title/> </cellNote> </cell>
不确定标题是否清楚,但基本上我有一些如下所示的XML: 测试1 不确定标题是否清楚,但基本上我有一些如下所示的 XML: <details> <result id=1234567890> <name>Test1</name> </result> <result id=5345345433> <name>Test2</name> </result> <result id=9572385354> <name>Test3</name> </result> 我想要完成的是找到使用已知值的 id 属性 即测试1 > 1234567890,测试2 > 5345345433,测试3 > 9572385354 最好使用 xmllint,但 xmlstarlet 也是一个选项。 输入 首先,您的 XML 无效。你的id属性需要被qouted,并且详细信息没有关闭。这是修改后的输入: <details> <result id="1234567890"> <name>Test1</name> </result> <result id="5345345433"> <name>Test2</name> </result> <result id="9572385354"> <name>Test3</name> </result> </details> 结果 下面将使用 xmlstarlet 提取给定 name 属性的特定 id。 xmlstarlet sel -t -c "/details/result[name='Test1']" test.xml | grep -Po "(?<=id=\")[\d]*" 这会回来 1234567890 您也可以将命令中的 Test1 替换为变量。 var=Test1 xmlstarlet sel -t -c "/details/result[name='$var']" test.xml | grep -Po "(?<=id=\")[\d]*" 故障 xmlstarlet sel -t -c "/details/result[name='$var']" test.xml 选择结果中与 $var 匹配的所有名称标签。 | grep -Po "(?<=id=\")[\d]*" 使用 Perl Regex 将输出通过管道传输到 grep 以查找 id 属性并打印所有包含的数字。 您还可以使用xmllint: xmllint --xpath "string(/details/result[name='Test1']/@id)" yourfile.xml --xpath:告诉 xmllint 使用 xpath 语法进行选择。 xpath选择器的详细信息: string(/details/result[name='Test1']/@id) string():制作字符串 /details/result:选择result元素的details子元素 [name='Test1']:包含一个name节点,其值为Test1 /@id:id属性值(result元素) 也许一个简单的 grep 和 awk 解决方案适合您。 grep -B1 Test1 sample.xml | awk '/id=/{gsub(/[^0-9]+/, "", $0); print $0 }' 完整回答OP的问题, #/bin/bash # # how to use xmllint to get information from specific elements # REQUIRES libxml2 (sorry Snow Leopard!) mytestxml=' <details> <result id="1234567890"> <name>Test1</name> </result> <result id="5345345433"> <name>Test2</name> </result> <result id="9572385354"> <name>Test3</name> </result> </details> ' echo Test Document is :"$mytestxml" echo Get the contents of the \''id'\' attribute of a specific \''result'\' element query=\''string(/details/result[3]/@id)'\' echo xpath query is "$query" myresult=$(echo "$mytestxml" | xmllint --xpath 'string(/details/result[3]/@id)' - ) echo info returned is "$myresult" echo "" echo Get the specific \''result'\' node whose \''name'\' element is \"Test1\" query=\''/details/result[name="Test1"]'\' echo xpath query is "$query" myresult=$(echo "$mytestxml" | xmllint --xpath '/details/result[name="Test1"]' - ) echo info returned is "$myresult" echo "" echo Get the \''id'\' attribute of the specific \''result'\' node whose \''name'\' element is \"Test1\" query=\''string(/details/result[name="Test1"]/@id)'\' echo combined xpath query is "$query" myresult=$(echo "$mytestxml" | xmllint --xpath 'string(/details/result[name="Test1"]/@id)' - ) echo info returned is "$myresult" 获取特定“result”元素的“id”属性的内容。 xpath 查询是: 'string(/details/result[3]/@id)' 返回的信息是:9572385354 获取'name'元素为“Test1”的特定'result'节点 xpath 查询是: '/details/result[name="Test1"]' 返回的信息是: <result id="1234567890"> <name>Test1</name> </result> 获取'name'元素为“Test1”的特定'result'节点的'id'属性 组合的 xpath 查询是: 'string(/details/result[name="Test1"]/@id)' 返回的信息是1234567890 希望这对找到此页面的其他人有用。 :o) 这样的东西应该与 xmlstarlet 一起使用(对我有用): xmlstarlet sel --template --match "/details/result[name='Test1']" --value-of "@id" test.xml
使用 xmlstarlet 更新现有 xml 文件元素的属性和值
我想编写一个脚本来迭代每个元素“NewTempP”的属性和子元素,并将结构复制到元素“fig”作为子元素。 “NewTempP”...
我有一个包含以下条目的 xml 文件: .... 我有一个包含以下条目的 xml 文件: .... <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/> <filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType> .... 我想在 <analyzer type="index"> 中注入以下 XML 节点: <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"/> 因此,最终的预期 XML 如下所示: .... <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/> <filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType> .... 为此,我尝试使用xmlstarlet,如下所示: xmlstarlet ed --inplace -s "//fieldType" -t elem -n "text_general" -i "//filter" -t attr -n "class" -v ""solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"" <file_name_here> 但显然,这不起作用(当我运行它时,它真的弄乱了我的 XML 文件!)。我对 xmlstarlet 很陌生,并且很难使用正确的语法来实现此目标。我也认为我的尝试中引用有问题。 您应该能够通过创建一个新的 filter 元素,然后向其添加属性来完成此操作(新的 filter 现在是 filter 中的最后一个 analyzer 元素)... xmlstarlet ed --inplace -s '//analyzer[@type="index"]' -t elem -n filter -i '//analyzer[@type="index"]/filter[last()]' -t attr -n class -v solr.NGramFilterFactory -i '//analyzer[@type="index"]/filter[last()]' -t attr -n minGramSize -v 1 -i '//analyzer[@type="index"]/filter[last()]' -t attr -n maxGramSize -v 20 input.xml 另一种选择是使用 XSLT。我认为这比尝试从命令行执行所有操作要容易得多... xmlstarlet tr so.xsl input.xml > output.xml XSLT 1.0(so.xsl) <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="analyzer[@type='index']"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
我有一个 XML 文档,我想使用 XMLStarlet 从所有元素(或给定类型的所有元素)中删除特定类型的所有属性及其值,而不干扰其...
如何使用 xmlstarlet 在另一个元素下插入一个新元素?
$ vim test.xml $ xmlstarlet ed -i "/config" -t elem -n "sub" -v "" test.xml ...
xmlstarlet。将多行中的多个值更改为 1 行,值之间用“---”分隔。可以吗?
我有这个xml文件(已截断) 34839473 12263522 我有这个 xml 文件(已截断) <adddata dn="articulo"> <attr name="code"> <value>34839473</value> <value>12263522</value> </attr> </adddata> 我想将多值行更新/替换为 1,值之间用“---”分隔。像这样: <attr name="code"> <value>34839473---12263522</value> </attr> 我尝试过: xmlstarlet ed -u "//attr[@name='code']" -x 'concat(value[1], "---", value[2])'` 并导致: <attr name="code">2312341---2348444</attr> 但我不知道如何在行中包含"<value>"和"</value>" 有什么建议吗? 提前致谢 我建议: xmlstarlet edit \ --omit-decl \ --update '//value[1]' --expr 'concat(//value[1], "---", //value[2])' \ --delete '//value[2]' file.xml 输出: <adddata dn="articulo"> <attr name="code"> <value>34839473---12263522</value> </attr> </adddata>