XSLT添加除少数之外的所有节点的前缀名称空间

时间:2016-01-18 08:22:19

标签: xml xslt

我正在尝试编写XSLT代码,以便为除少数几个节点之外的所有节点添加前缀命名空间。

示例XML:

    <BatchPrepareDeliverArchive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="schema">
<BatchInformation>
    <RqUId>424000000071256187550913330</RqUId>
    <BatchFeedId>CMLTREXT4240</BatchFeedId>
    <BatchCount>7</BatchCount>
</BatchInformation>
<BatchDeliverArchive>
    <Transactions>
        <Transaction>
            <TransactionUUID>90022016-01-140000001</TransactionUUID>
            <CustomerData>
                <GBD_Transactions>
                    <GBD_Transaction>
                        <Common_Data>
                            <Transaction_ID>90022016-01-140000001</Transaction_ID>
                            </Common_Data>
                        <Templates>
                            <Template>
                                <Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
                                <Transaction_ID>90022016-01-140000001</Transaction_ID>
                                </Template>
                        </Templates>
                    </GBD_Transaction>
                </GBD_Transactions>
            </CustomerData>
            <DocInfo>
                <Name>OPERATION NAME</Name>
                </DocInfo>
            </Transaction>
            </Transactions>
            </BatchDeliverArchive>
    </BatchPrepareDeliverArchive>

我想在所有节点上添加 urn 前缀,但 GBD_Transactions &amp;它的子元素。

我想出了这个XSLT:

    <xsl:stylesheet version="1.0"  xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="*">
    <xsl:element name="urn:{local-name()}">
    <xsl:apply-templates/>
    </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
    <xsl:element name="urn:{local-name()}">
    <xsl:value-of select="."/>
    </xsl:element>
    </xsl:template>

    </xsl:stylesheet>

所有节点都在此处进行转换,这不是预期的输出。 非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

如果要忽略GBD_Transactions元素及其后代,只需添加模板以匹配相关节点,并使用标识模板按原样复制它们。

尝试将此模板添加到XSLT

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

请注意,对特定元素名称的匹配优先级高于*上的匹配优先级,因此应始终在更通用的模板之前使用此模板。

顺便说一句,您的模板存在与“#34; *&#34;”匹配的问题。你可能把它改成了......

<xsl:template match="*">
  <xsl:element name="urn:{local-name()}">
    <xsl:apply-templates select="@*|node()" />
   </xsl:element>
</xsl:template>

这是因为<xsl:apply-templates />与执行<xsl:apply-templates select="node()" />相同,因此不会选择属性。因此,与@*匹配的现有模板不会被调用。

编辑:如果要阻止xsi:schemaLocation属性成为元素,也要添加此模板(您需要在XSLT中声明xsi命名空间)

<xsl:template match="@xsi:*">
    <xsl:copy />
</xsl:template>

或者您可能不希望任何属性更改为元素?试试这个XSLT吧?

<xsl:stylesheet version="1.0"  xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="*">
    <xsl:element name="urn:{local-name()}">
    <xsl:apply-templates select="@*|node()" />
    </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:copy />
    </xsl:template>

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

答案 1 :(得分:0)

在匹配&#34; *&#34;的模板中,您应该区分如下:

<xsl:template match="*">
    <xsl:choose>
        <xsl:when test="ancestor-or-self::GBD_Transactions">
            <xsl:copy>
                <xsl:apply-templates"/>
            </xsl:copy>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="urn:{local-name()}">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

输出将如下所示:

<urn:BatchPrepareDeliverArchive xmlns:urn="http://www.w3.org/2001/XMLSchema-instance">
    <urn:BatchInformation>
        <urn:RqUId>424000000071256187550913330</urn:RqUId>
        <urn:BatchFeedId>CMLTREXT4240</urn:BatchFeedId>
        <urn:BatchCount>7</urn:BatchCount>
    </urn:BatchInformation>
    <urn:BatchDeliverArchive>
        <urn:Transactions>
            <urn:Transaction>
                <urn:TransactionUUID>90022016-01-140000001</urn:TransactionUUID>
                <urn:CustomerData>
                    <GBD_Transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                        <GBD_Transaction>
                            <Common_Data>
                                <Transaction_ID>90022016-01-140000001</Transaction_ID>
                            </Common_Data>
                            <Templates>
                                <Template>
                                    <Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
                                    <Transaction_ID>90022016-01-140000001</Transaction_ID>
                                </Template>
                            </Templates>
                        </GBD_Transaction>
                    </GBD_Transactions>
                </urn:CustomerData>
                <urn:DocInfo>
                    <urn:Name>OPERATION NAME</urn:Name>
                </urn:DocInfo>
            </urn:Transaction>
        </urn:Transactions>
    </urn:BatchDeliverArchive>
</urn:BatchPrepareDeliverArchive>

这就是你想要的吗?