[英]XSLT copy, apply-templates select=“@*|node()” only copies node values
如果XML在根节点上匹配,我想将节点从源复制到输出。 我尝试使用:
<xsl:stylesheet version="1.0" xmlns:i="http://www.somestuff.com xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/i:Root">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用此输入xml,我在根节点上进行匹配,但输出仅获取节点的值。
<?xml version="1.0" encoding="utf-8"?>
<i:Root xmlns:i="http://www.somestuff.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance>
<i:Info>
<i:Num1>1234567890</i:Num1>
<i:Num2>1234567890</i:Num2>
<i:Service> code="1">String</i:Service>
<i:Type code="0">String</i:Type>
<i:Source>V</i:Source>
<i:MainNum>1234567890</i:MainNum>
<i:Name>a</i:Name>
<i:Code>a</i:Code>
<i:AttentionIndicator code="1">String</i:AttentionIndicator>
<i:SpecialMessage>a</i:SpecialMessage>
<i:AdditionalInfo>a</i:AdditionalInfo>
</i:Info>
</i:Root>
输出:
<?xml version="1.0" encoding="utf-8"?><i:Root xmlns:i="http://www.somestuff.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1234567890
1234567890
String
String
V
1234567890
a
a
String
a
a
</i:Root>
似乎我缺少了一些非常简单的东西,例如Apply模板无法按照我的方式工作。 谢谢您的帮助!
如果根节点匹配i:Root,我想直接获得输入XML的副本。
然后,像Kevin的回答中那样进行简单的身份转换将无济于事,因为无论最外面的节点是否被称为i:Root
都将复制文档。 为什么? 因为即使在这种情况下不调用与/i:Root
匹配的模板,也要调用另一个。
检查document元素的名称后,使用xsl:copy-of
元素有效地复制所有内容。
样式表
<xsl:stylesheet version="1.0" xmlns:i="http://www.somestuff.com"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:if test="self::i:Root">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
现在,如果我们将XML Input更改为:
<?xml version="1.0" encoding="utf-8"?>
<i:SomethingElse xmlns:i="http://www.somestuff.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<i:Info>
<i:Num1>1234567890</i:Num1>
<i:Num2>1234567890</i:Num2>
<i:Service> code="1">String</i:Service>
<i:Type code="0">String</i:Type>
<i:Source>V</i:Source>
<i:MainNum>1234567890</i:MainNum>
<i:Name>a</i:Name>
<i:Code>a</i:Code>
<i:AttentionIndicator code="1">String</i:AttentionIndicator>
<i:SpecialMessage>a</i:SpecialMessage>
<i:AdditionalInfo>a</i:AdditionalInfo>
</i:Info>
</i:SomethingElse>
正如预期的那样,我们得到以下输出:
<?xml version="1.0" encoding="utf-8"?>
否则(即,如果document元素称为i:Root
),则输出XML是输入的精确副本。 您可以在此处在线尝试其他输入。
是的,您缺少了一些东西,但是您的xsl:apply-template
或select没有错。
您除了i:Root之外,还缺少其他节点的模板,这类似于:
<xsl:stylesheet version="1.0" xmlns:i="http://www.somestuff.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/i:Root">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果您未定义模板,则xslt处理器将退回到其内置模板。
内置模板将用于节点:
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
与文本节点的内置模板结合使用:
<xsl:template match="text( )|@*">
<xsl:value-of select="."/>
</xsl:template>
...仅显示您的文字。
编辑:只需阅读您对获得直接副本的评论:
<xsl:stylesheet version="1.0" xmlns:i="http://www.somestuff.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/i:Root">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/*" priority="-1">
<Empty/><!-- or sth creative, but valid xml should have a root node -->
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.