将动态命名空间更改为XSLT中的节点和元素

时间:2016-09-13 08:46:55

标签: xml xslt namespaces

源xml可以为下面示例中的NativeTrxDetail节点提供不同的ns前缀:

<?xml version="1.0" encoding="UTF-8"?>
<VLog xmlns="http://www.university.com/integration/" xmlns:tri="http://www.university.com/integration/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratingCodeVersion="2.5.2.0.717" Version="1.0"
        xsi:schemaLocation="http://www.university.com/integration/VLog.xsd">
    <Header>
        <MessageId>08c5a8c055a685d6a71a77</MessageId>
        <Timestamp>2016-03-17T16:00:01</Timestamp>
    </Header>
    <Body>
        <tri:Transaction xmlns="http://www.f-arts.org/namespace/" Version="1.0" xsi:type="RetailTransactionStockView">
            <RetailStoreID>Bud053</RetailStoreID>
            <WorkstationID>1</WorkstationID>
            <tri:NativeTrxDetail>
                <tri:ApplicationID>POS</tri:ApplicationID>
                <tri:OrganizationID>Bud</tri:OrganizationID>
                <tri:TillCharacteristics>
                    <tri:TillDeviceID/>
                    <tri:TillOperatorID/>
                </tri:TillCharacteristics>
            </tri:NativeTrxDetail>
            <OperatorID>92053</OperatorID>
            <CurrencyCode>NZD</CurrencyCode>
            <TillID>770</TillID>
            <TillSupervisor>92053</TillSupervisor>
            <LineItem>
                <SequenceNumber>1</SequenceNumber>
                <EndDateTime>2016-08-17T16:00:33</EndDateTime>
                <tri:NativeLineDetail>
                    <tri:LineNumber>29</tri:LineNumber>
                    <tri:LineType>CurrentTransaction</tri:LineType>
                    <tri:ActionCode>POST_VOID_SALE</tri:ActionCode>
                </tri:NativeLineDetail>
                <SupplementalData/>
                <Command/>
            </LineItem>
            <Total TotalType="TransactionGrandAmount">
                <Amount>-0.55</Amount>
            </Total>
            <TransactionLink ReasonCode="PostVoid">
                <BusinessDayDate>2016-08-17</BusinessDayDate>
            </TransactionLink>
        </tri:Transaction>
    </Body>
</VLog>

我需要更改 NativeTrxDetail 的ns,尽管还有其他节点/元素带有tri。

所需的输出是:

<?xml version="1.0"?>
<ns0:VLog xmlns:b="http://www.f-arts.org/namespace/" xmlns:a="http://www.university.com/integration/" xmlns:ns1="http://www.f-arts.org/namespace/" xmlns:ns0="http://www.university.com/integration/">
    <ns0:Header>
        <ns0:MessageId>08c5a8c055a685d6a71a77</ns0:MessageId>
        <ns0:Timestamp>2016-03-17T16:00:01</ns0:Timestamp>
    </ns0:Header>
    <ns0:Body>
        <ns0:Transaction>
            <ns1:RetailStoreID>Bud053</ns1:RetailStoreID>
            <ns1:WorkstationID>1</ns1:WorkstationID>
            <ns1:NativeTrxDetail>
                <ns0:ApplicationID>POS</ns0:ApplicationID>
                <ns0:OrganizationID>Bud</ns0:OrganizationID>
            </ns1:NativeTrxDetail>
        </ns0:Transaction>
    </ns0:Body>
</ns0:VLog>

我能够通过以下方式实现这一目标:

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.university.com/integration/" xmlns:ns1="http://www.f-arts.org/namespace/" xmlns:b="http://www.f-arts.org/namespace/">
    <xsl:template match="/">
        <ns0:VLog xmlns:ns0="http://www.university.com/integration/">
            <ns0:Header>
                <ns0:MessageId>
                    <xsl:value-of select="//*[local-name()='MessageId']"/>
                </ns0:MessageId>
                <ns0:Timestamp>
                    <xsl:value-of select="//*[local-name()='Timestamp']"/>
                </ns0:Timestamp>
            </ns0:Header>
            <ns0:Body>
                <ns0:Transaction>
                    <ns1:RetailStoreID>
                        <xsl:value-of select="//*[local-name()='RetailStoreID']"/>
                    </ns1:RetailStoreID>
                    <ns1:WorkstationID>
                        <xsl:value-of select="//*[local-name()='WorkstationID']"/>
                    </ns1:WorkstationID>
                    <ns1:NativeTrxDetail>
                        <ns0:ApplicationID>
                            <xsl:value-of select="//*[local-name()='ApplicationID']"/>
                        </ns0:ApplicationID>
                        <ns0:OrganizationID>
                            <xsl:value-of select="//*[local-name()='OrganizationID']"/>
                        </ns0:OrganizationID>
                    </ns1:NativeTrxDetail>
                </ns0:Transaction>
            </ns0:Body>
        </ns0:VLog>
    </xsl:template>
</xsl:stylesheet>

我需要这样做,以便我不需要逐个映射每个元素,因为源xml中有许多这样的节点需要相同的处理。

我尝试了下面的代码,但它不起作用:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tri="http://www.university.com/TE/integration/" xmlns:ns1="http://www.university.com/integration/" xmlns = "http://www.f-arts.org/namespace/" >
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <!-- template to handle elements -->
    <xsl:template match="tri:NativeTrxDetail">
        <xsl:element name="ns1:{local-name()}">
            <xsl:apply-templates select="node() | @*"/>
        </xsl:element>
    </xsl:template>
      <xsl:template match="@tri:NativeTrxDetail">
    <xsl:attribute name="ns1:{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

请帮忙。

非常感谢 Bhamber

1 个答案:

答案 0 :(得分:1)

你的问题令人困惑。您说您只想更改NativeTrxDetail的名称空间,但您的输出会添加或更改所有节点的名称空间前缀 - 并且没有明显的原因。并非所有节点都传递给输出。

分配给命名空间的前缀没有意义,因此可以通过以下方式非常简单地实现所请求的任务:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:univ="http://www.university.com/integration/"
exclude-result-prefixes="univ">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="univ:NativeTrxDetail">
    <NativeTrxDetail xmlns="http://www.f-arts.org/namespace/">
        <xsl:apply-templates select="@*|node()"/>
    </NativeTrxDetail>
</xsl:template>

</xsl:stylesheet>

无论源XML分配给NativeTrxDetail的前缀是什么,只要它绑定到"http://www.university.com/integration/">命名空间URI,这都可以。