我正在尝试将一个节点的节点内容复制到另一个节点。基本上节点内容应该与第一个节点中的相同,除了不应该替换第二个节点中的引号。
我找到了一些代码并对其进行了修改,但它只复制了第一个节点内容的第一个外观。
这是我到目前为止的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>
也许有人可以帮助我找到解决方案或指出我正确的方向。
非常感谢提前
答案 0 :(得分:1)
您的方法不起作用,因为XPath表达式
/strings/string/de/text()
有几个结果,在这种情况下有三个。如果你把它们放在这样的参数中:
<xsl:param name="pReplacement" select="/strings/string/de/text()"/>
然后所有三个结果节点将成为pReplacement
的一部分。如果在预期只有一个节点的位置使用一组节点,例如
<xsl:value-of select="$pReplacement"/>
然后只为此操作选择 first 节点。
您无需更改,只需取消顶级参数并将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
元素之前。最后,如果在de
元素之前有多个es
元素,如果您使用的是XSLT 2.0,则可能会出现问题,因为它只会连接前面所有de
的字符串值元件。