使用 XSLT 将 XML 中的节点复制到另一个位置
Copy Node in XML to another position using XSLT
如果节点的值与下面的节点匹配,我会尝试替换它。
为此,我需要一个 xls 转换脚本。
如何将 XML 部分复制到另一个部分?
<persons>
<person>
<name>Peter</name>
<surname>Muster</surname>
<address>
<object>addresses/address1</object>
</address>
</person>
<person>
<name>Lisa</name>
<surname>Muster</surname>
<address>
<object>addresses/address1</object>
</address>
</person>
<person>
<name>John</name>
<surname>Smith</surname>
<address>
<object>addresses/address3</object>
</address>
</person>
<persons>
<addresses>
<address1>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address1>
<address2>
<street>road2</street>
<zip>77777</zip>
<town>Sunvillage</town>
</address2>
<address3>
<street>road3</street>
<zip>88888</zip>
<town>Venusvillage</town>
</address3>
</addresses>
结果XML必须是这样的:
<persons>
<person>
<name>Peter</name>
<surname>Muster</surname>
<address>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address>
</person>
<person>
<name>Lisa</name>
<surname>Muster</surname>
<address>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address>
</person>
<person>
<name>John</name>
<surname>Smith</surname>
<address>
<street>road3</street>
<zip>88888</zip>
<town>Venusvillage</town>
</address>
</person>
<persons>
最后xml中的地址不需要删除。
目前我正在尝试匹配“对象”和副本。但现在它不起作用了。
使用 XSLT 3 并支持 xsl:evaluate
(即 Saxon 10 所有版本、Saxon-JS 2、Saxon 9.8 和 9.9 商业版、Altova XMLSpy/Raptor)它可能可以解决为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="person/address">
<xsl:copy>
<xsl:evaluate xpath=". || '/*'" context-item="/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="addresses"/>
</xsl:stylesheet>
Martin Honnen 的回答更好,因为它评估了提供的 XPath,但如果您仅限于 XSLT 1.0,您可以尝试这样的事情:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="addresses"/>
<xsl:template match="address/object">
<xsl:variable name="elemName" select="substring-after(.,'/')"/>
<xsl:copy-of select="//addresses/*[name()=$elemName]/*"/>
</xsl:template>
</xsl:stylesheet>
如果节点的值与下面的节点匹配,我会尝试替换它。 为此,我需要一个 xls 转换脚本。
如何将 XML 部分复制到另一个部分?
<persons>
<person>
<name>Peter</name>
<surname>Muster</surname>
<address>
<object>addresses/address1</object>
</address>
</person>
<person>
<name>Lisa</name>
<surname>Muster</surname>
<address>
<object>addresses/address1</object>
</address>
</person>
<person>
<name>John</name>
<surname>Smith</surname>
<address>
<object>addresses/address3</object>
</address>
</person>
<persons>
<addresses>
<address1>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address1>
<address2>
<street>road2</street>
<zip>77777</zip>
<town>Sunvillage</town>
</address2>
<address3>
<street>road3</street>
<zip>88888</zip>
<town>Venusvillage</town>
</address3>
</addresses>
结果XML必须是这样的:
<persons>
<person>
<name>Peter</name>
<surname>Muster</surname>
<address>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address>
</person>
<person>
<name>Lisa</name>
<surname>Muster</surname>
<address>
<street>road1</street>
<zip>66666</zip>
<town>Moonvillage</town>
</address>
</person>
<person>
<name>John</name>
<surname>Smith</surname>
<address>
<street>road3</street>
<zip>88888</zip>
<town>Venusvillage</town>
</address>
</person>
<persons>
最后xml中的地址不需要删除。
目前我正在尝试匹配“对象”和副本。但现在它不起作用了。
使用 XSLT 3 并支持 xsl:evaluate
(即 Saxon 10 所有版本、Saxon-JS 2、Saxon 9.8 和 9.9 商业版、Altova XMLSpy/Raptor)它可能可以解决为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="person/address">
<xsl:copy>
<xsl:evaluate xpath=". || '/*'" context-item="/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="addresses"/>
</xsl:stylesheet>
Martin Honnen 的回答更好,因为它评估了提供的 XPath,但如果您仅限于 XSLT 1.0,您可以尝试这样的事情:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="addresses"/>
<xsl:template match="address/object">
<xsl:variable name="elemName" select="substring-after(.,'/')"/>
<xsl:copy-of select="//addresses/*[name()=$elemName]/*"/>
</xsl:template>
</xsl:stylesheet>