我是XSL / XSLT的新手。我试图将新元素(数据源)添加到此xml的所有用户元素中:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user id="1">
<repo>r1</repo>
<home>h1</home>
</user>
<user id="2">
<repo>r2</repo>
<home>h2</home>
</user>
<user id="3">
<repo>r3</repo>
<home>h3</home>
</user>
<user id="4">
<repo>r4</repo>
<home>h4</home>
</user>
<user id="5">
<repo>r5</repo>
<home>h5</home>
</user>
</users>
我正在使用这个XSL脚本:
<?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" cdata-section-elements="configXml"/>
<!-- Copy everything -->
<xsl:template match="node()">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/users/user[*]">
<xsl:copy>
<xsl:apply-templates/>
<xsl:element name="datasources"></xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
问题是,在最终结果所有用户的ID消失:
<users>
<user>
<repo>r1</repo>
<home>h1</home>
<datasources/>
</user>
<user>
<repo>r2</repo>
<home>h2</home>
<datasources/>
</user>
<user>
<repo>r3</repo>
<home>h3</home>
<datasources/>
</user>
<user>
<repo>r4</repo>
<home>h4</home>
<datasources/>
</user>
<user>
<repo>r5</repo>
<home>h5</home>
<datasources/>
</user>
如何在输出中保留用户ID?
答案 0 :(得分:2)
您的副本所有模板都需要:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
请参阅How to copy everything as is and only remove a specific element。
正在发生的事情是您的第二个模板与<user>
元素匹配,但<apply-templates/>
不会在属性上使用第一个模板,因为它们与node()
不匹配
正如Ian Roberts指出的那样,您还需要在第二个模板的@*|node()
中明确选择<xsl:apply-templates/>
,以便处理属性 - 在这种情况下,它们将被选中修改后的第一个模板。
所以完整的解决方案是:
<?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" cdata-section-elements="configXml"/>
<!-- Copy everything -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/users/user[*]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:element name="datasources"></xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
不会复制属性,因为您还没有复制它们 - 遵循其他模板的模式,您需要在/users/user[*]
模板中添加
<xsl:copy-of select="@*"/>
作为向儿童应用模板之前<xsl:copy>
中的第一件事。