XSLT/XML 将节点的值复制到节点
XSLT/XML Copy value of node to node
我正在尝试将一个节点的节点内容复制到另一个节点。基本上节点内容应该和第一个节点一样,只是第二个节点的引号不要替换。
我找到了一些代码并修改了它,但是它只复制了第一个节点内容的第一次出现。
这是我到目前为止的 xslt 代码。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pReplacement" select="/strings/string/de/text()"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="strings/string/es/text()">
<xsl:value-of select="$pReplacement"/>
</xsl:template>
</xsl:stylesheet>
输入XML是:
<?xml version="1.0"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>""</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>""</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>""</es>
</string>
</strings>
错误的输出是:
<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>something1</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>something1</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>something1</es>
</string>
</strings>
所需的输出应如下所示。
<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>"something1"</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>"something2"</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>"something3"</es>
</string>
</strings>
也许有人可以帮助我找到解决方案或为我指明正确的方向。
非常感谢
您的方法无效,因为 XPath 表达式
/strings/string/de/text()
有几个 个结果,在本例中为三个。如果你把它们放在这样的参数中:
<xsl:param name="pReplacement" select="/strings/string/de/text()"/>
然后所有三个结果节点将成为pReplacement
的一部分。如果您在预期只有一个节点的地方使用一组节点,例如
<xsl:value-of select="$pReplacement"/>
那么只有第一个节点会被选中进行这个操作。
没有太多你需要改变的,只是取消top-level参数并将strings/string/es/text()
的内容替换为
<xsl:value-of select="../../de"/>
XSLT 样式表
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="strings/string/es/text()">
<xsl:value-of select="../../de"/>
</xsl:template>
</xsl:stylesheet>
XML输出
<strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>something1</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>something2</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>something3</es>
</string>
</strings>
在线尝试此解决方案 here。
编辑
如果文档中的所有 es
元素都应受到此更改的影响,您还可以将模板编写为
<xsl:template match="es/text()">
<xsl:value-of select="../preceding-sibling::de"/>
</xsl:template>
但这需要始终有一个 de
元素作为 string
元素的子元素,并且它始终在 es
元素之前。最后,如果在 es
元素之前有多个 de
元素,如果您使用 XSLT 2.0,这可能会成为问题,因为它会简单地连接前面所有 de
的字符串值元素。
我正在尝试将一个节点的节点内容复制到另一个节点。基本上节点内容应该和第一个节点一样,只是第二个节点的引号不要替换。
我找到了一些代码并修改了它,但是它只复制了第一个节点内容的第一次出现。
这是我到目前为止的 xslt 代码。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pReplacement" select="/strings/string/de/text()"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="strings/string/es/text()">
<xsl:value-of select="$pReplacement"/>
</xsl:template>
</xsl:stylesheet>
输入XML是:
<?xml version="1.0"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>""</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>""</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>""</es>
</string>
</strings>
错误的输出是:
<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>something1</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>something1</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>something1</es>
</string>
</strings>
所需的输出应如下所示。
<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>"something1"</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>"something2"</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>"something3"</es>
</string>
</strings>
也许有人可以帮助我找到解决方案或为我指明正确的方向。
非常感谢
您的方法无效,因为 XPath 表达式
/strings/string/de/text()
有几个 个结果,在本例中为三个。如果你把它们放在这样的参数中:
<xsl:param name="pReplacement" select="/strings/string/de/text()"/>
然后所有三个结果节点将成为pReplacement
的一部分。如果您在预期只有一个节点的地方使用一组节点,例如
<xsl:value-of select="$pReplacement"/>
那么只有第一个节点会被选中进行这个操作。
没有太多你需要改变的,只是取消top-level参数并将strings/string/es/text()
的内容替换为
<xsl:value-of select="../../de"/>
XSLT 样式表
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="strings/string/es/text()">
<xsl:value-of select="../../de"/>
</xsl:template>
</xsl:stylesheet>
XML输出
<strings>
<string name="cpu">
<en>example1</en>
<de>something1</de>
<es>something1</es>
</string>
<string name="gpu">
<en>example2</en>
<de>something2</de>
<es>something2</es>
</string>
<string name="mainboard">
<en>example3</en>
<de>something3</de>
<es>something3</es>
</string>
</strings>
在线尝试此解决方案 here。
编辑
如果文档中的所有 es
元素都应受到此更改的影响,您还可以将模板编写为
<xsl:template match="es/text()">
<xsl:value-of select="../preceding-sibling::de"/>
</xsl:template>
但这需要始终有一个 de
元素作为 string
元素的子元素,并且它始终在 es
元素之前。最后,如果在 es
元素之前有多个 de
元素,如果您使用 XSLT 2.0,这可能会成为问题,因为它会简单地连接前面所有 de
的字符串值元素。