在执行<xsl:apply-templates select =“@ * | node()”>时保持schemaversion

时间:2017-04-26 14:00:26

标签: xslt xslt-1.0

我有复制整个节点的要求,包括schemaversion和名称空间。 (以下是XML的一部分)

<ns0:Body>
<std:test com:schemaVersion = "4.1" xmlns:com = "http://www.test.com/DI/D2P/Broker/Schemas/CommonTypes" xmlns:std = "http://www.test1.com/DI/D2P/Broker/Schemas/test" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance">
<com:SystemMessageHeader>
...
...

我在xslt下面使用它来完成这项任务。 (我已经提到过只需要XSLT的一部分。)使用这个XSLT,它会复制整个节点,包括命名空间,但它不会复制com:schemaVersion =“4.1”。请帮帮我怎么解决?

<nos:Body>
    <xsl:for-each select ="nos:GRRCall/nos:Response/ns0:Body/*">
        <xsl:copy>
            <xsl:variable name="v1" select="position()"/>
            <xsl:variable name="v2" select="count(../../../../*)"/>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:for-each>
</nos:Body>


<xsl:template match="@*|node()">
<xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
    <xsl:apply-templates select="com:SystemMessageHeader"/>
</xsl:copy>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

当您执行apply-templates而未指定select表达式时 - 如在样式表片段中 - 未选择上下文节点的属性进行转换。这就是规范身份转换明确选择属性的原因:

<!-- Identity transform -->
<xsl:template match="node()|@*">
  <xsl:copy>
    <!-- HERE: -->
    <xsl:apply-templates select="node()|@* />
  </xsl:copy>
</xsl:template>

然后,当您将模板应用于<ns0:Body>元素的子元素时,您的第一个选择是遵循身份转换的模型。

您的第二个选择是通过添加...

显式转换所需属性
    <xsl:apply-templates select="@com:schemaVersion" />

...不会影响其他属性,如果源元素没有这样的属性,它将不执行任何操作。

第三种方法是确保转换后的元素具有所需属性,即使源元素没有,也可以通过插入代码在模板中创建一个:

    <xsl:attribute name="com:schemaVersion">
      <xsl:value-of select="@com:schemaVersion" />
    </xsl:attribute>

当源节点没有这样的属性时,该特定版本将提供一个空字符串作为属性值;如果需要,您可以修改它以提供默认值。