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>

我想向除GBD_Transactions及其子元素以外的所有节点添加 urn 前缀。

我想出了这个 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>

所有节点都在这里转换,这不是预期的输出。将不胜感激对此的任何帮助!

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

尝试将此模板添加到 XSLT

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

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

顺便说一下,您的模板与"*"匹配存在问题。您可能会将其更改为此...

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

在与"*"匹配的模板中,您应该像这样区分:

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

这就是你想要的吗?

最新更新