XSLT copy,apply-templates select =" @ * | node()"仅复制节点值

时间:2014-08-19 16:39:03

标签: xml xslt

如果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-templates不按我想象的方式工作。谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

  

如果是根节点,我想直接获得输入XML的副本   匹配i:Root。

然后,凯文的答案中的简单身份变换将无济于事,因为无论最外层节点是否被调用i:Root,都会复制文档。为什么?因为即使在这种情况下不调用匹配/i:Root的模板,另一个是。

在检查文档元素的名称后,使用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输入更改为:

<?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"?>

否则(即,如果文档元素被称为i:Root),输出XML就是输入的精确副本。自己在线尝试不同的输入,here

答案 1 :(得分:0)

是的,您错过了一些内容,但您的xsl:apply-template或选择此内容没有任何问题。

除了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>