想象一下,我有以下XML文件:
&LT a取代;之前&LT b取代;中间< / B>在< / A>
我想把它转换成这样的东西:
&LT a取代; beforemiddleafter< / A>
换句话说,我希望得到某个节点的所有子节点,并按顺序将它们移动到父节点。这就像执行此命令:“mv ./directory/*。”,但对于xml节点。
我想在使用unix命令行工具时这样做。我一直在尝试使用xmlstarlet,它是一个功能强大的命令行XML操作器。我尝试过这样的事情,但它不起作用
在< / a>之后< b>中< / b>之前回显“< a>” | xmlstarlet ed -m“// b / *”“..”
更新:XSLT模板很好,因为可以从命令行调用它们。
我的目标是“从XHTML页面删除链接”,换句话说,用链接标记的内容替换链接的位置。
答案 0 :(得分:3)
示例输入文件(test.xml):
<?xml version="1.0" encoding="UTF-8"?>
<test>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<a>before<b>middle</b>after</a>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<embedded>foo<a>before<b>middle</b>after</a>bar</embedded>
</test>
XSLT样式表(collapse.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用
运行XmlStarletxml tr collapse.xsl test.xml
产地:
<?xml version="1.0"?>
<test>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<a>beforemiddleafter</a>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<embedded>foo<a>beforemiddleafter</a>bar</embedded>
</test>
样式表中的第一个模板是基本身份转换(只复制整个输入XML文档)。第二个模板专门匹配您要“折叠”的元素,只复制标记并插入元素的字符串值(=后代节点的字符串值的串联)。
答案 1 :(得分:2)
在XSLT中,你可以写:
<xsl:template match="a"><a><xsl:apply-templates /></a></xsl:template>
<xsl:template match="a/b"><xsl:value-of select="."/></xsl:template>
你会得到:
<a>beforemiddleafter</a>
因此,如果您想以简单的方式创建XSL样式表并通过它运行XML文件。
然而,我意识到这不是你所说的(使用Unix命令行)。我对Unix一无所知,也许其他人可以填写空白,例如。某种可以执行上述命令行调用。
答案 2 :(得分:2)
如果您的实际目标是从网页中删除链接,那么您应该使用这样的样式表,它匹配所有XHTML <a>
元素(我假设您正在使用XHTML?)并且只是将模板应用于其内容:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="h">
<!-- Don't copy the <a> elements, just process their content -->
<xsl:template match="h:a">
<xsl:apply-templates />
</xsl:template>
<!-- identity template; copies everything by default -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
此样式表将处理您希望保留的<{em> 元素中嵌套的情况,例如:
<a>
你想成为:
<p>Here is <a href="....">some <em>linked</em> text</a>.</p>
它将处理嵌套在通常的父(<p>Here is some <em>linked</em> text.</p>
元素)和<p>
元素之间的意外元素中的链接的情况,例如:
<a>
答案 3 :(得分:1)
使用xmlstarlet:
xmlstr='<a>before<b>middle</b>after</a>'
updatestr="$(echo "$xmlstr" | xmlstarlet sel -T -t -m "/a/b" -v '../.' -n | sed -n '1{p;q;}')"
echo "$xmlstr" | xmlstarlet ed -u "/a" -v "$updatestr"
答案 4 :(得分:0)
你试过这个吗?
file.xml
<r>
<a>start<b>middle</b>end</a>
</r>
template.xsl
<xsl:template match="/">
<a><xsl:value-of select="r/a" /></a>
</xsl:template>
output
<a>startmiddleend</a>