我创建了一个XSLT,我想知道如何在一组标签之间复制所有节点,并在底部添加另一个标签。我创建了XSLT,它具有确定要添加哪个标记以及应该调用的标记的所有逻辑。但是我现在遇到的问题是我无法复制所有其他标签。以下是有问题的文件:
XSLT
<?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="/csvImportSchema">
<csvImportSchema>
<xsl:for-each select="payload">
<payload>
<xsl:copy-of select="@*"/>
<xsl:variable name="ean">
<xsl:value-of select="ean"/>
</xsl:variable>
<xsl:for-each select="../product">
<xsl:if test="ean = $ean">
<productId><xsl:value-of select="article"/></productId>
</xsl:if>
</xsl:for-each>
</payload>
</xsl:for-each>
</csvImportSchema>
</xsl:template>
</xsl:stylesheet>
INPUT
<?xml version="1.0" encoding="UTF-8"?>
<csvImportSchema>
<payload>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
<ean>1111111111</ean>
<productId/>
</payload>
<product>
<article>722619</article>
<ean>1111111111</ean>
</product>
</csvImportSchema>
当前输出
<?xml version="1.0" encoding="utf-8"?>
<csvImportSchema>
<payload>
<productId>722619</productId>
</payload>
</csvImportSchema>
渴望输出
<?xml version="1.0" encoding="UTF-8"?>
<csvImportSchema>
<payload>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
<ean>1111111111</ean>
<productId>722619</productId>
</payload>
</csvImportSchema>
答案 0 :(得分:8)
这个简短而简单的转型:
<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="productId">
<productId>
<xsl:value-of select="../../product/article"/>
</productId>
</xsl:template>
<xsl:template match="product"/>
</xsl:stylesheet>
应用于提供的XML文档时:
<csvImportSchema>
<payload>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
<ean>1111111111</ean>
<productId/>
</payload>
<product>
<article>722619</article>
<ean>1111111111</ean>
</product>
</csvImportSchema>
生成想要的正确结果:
<csvImportSchema>
<payload>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
<ean>1111111111</ean>
<productId>722619</productId>
</payload>
</csvImportSchema>
<强>解释强>:
identity rule 按“原样”复制选择执行它的每个节点。
匹配product
的覆盖模板“从输出中删除”此元素(通过其空体)。
另一个覆盖模板与productId
匹配,并使用取自product/article
的文本节点子项生成此元素。
答案 1 :(得分:1)
应该像将有效负载xsl:copy-of select="@*"/
更改为
<xsl:copy-of select="*[local-name() != 'productId'] | @*"/>
即。复制除productId
之外的所有内容,因为您手动构建了它。
这提供了您所需的输出
<?xml version="1.0" encoding="utf-8"?>
<csvImportSchema>
<payload>
<test>1</test>
<test2>2</test2>
<test3>3</test3>
<ean>1111111111</ean>
<productId>722619</productId>
</payload>
</csvImportSchema>
答案 2 :(得分:1)
这个XSLT应该完成这项工作并使用更多的COPY标签和模板。也许不要在一个xsl:template(我的意见)中做所有事情。
<?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="/csvImportSchema">
<xsl:copy>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="csvImportSchema/payload/productId">
<xsl:variable name="ean">
<xsl:value-of select="../ean"/>
</xsl:variable>
<xsl:for-each select="../../product">
<xsl:if test="ean = $ean">
<productId><xsl:value-of select="article"/></productId>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="csvImportSchema/product">
<!-- do not copy -->
</xsl:template>
<xsl:template match="csvImportSchema/payload">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>