繁体   English   中英

XSLT复制,应用模板选择=“ @ * | node()”仅复制节点值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM