XSLT在输出上保留命名空间

时间:2017-04-11 02:24:18

标签: xslt xml-namespaces

我需要帮助在XSLT转换上保留命名空间。我看到其他线程有解决方案,但我不理解它们。当我在下面使用XSLT转换时,所有命名空间都会消失。以下是我想要完成的事情。任何帮助深表感谢!谢谢!

转换XML之前:

<?xml version='1.0' encoding='UTF-8'?>
<Worker
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:this="this.file/eib"
    xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
    xmlns:tv="java:com.workday.esb.intsys.TypedValue">
    <Detail>
        <EmployeeID>123456</EmployeeID>
        <PayCode>Earning</PayCode>
        <Amount>4243.20</Amount>
    </Detail>
    <Detail>
        <EmployeeID>123456</EmployeeID>
        <PayCode>Deduction</PayCode>
        <Amount>2265.60</Amount>
    </Detail>
</Worker>

我的XSLT转型:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xsl wd is xsd this env"
    xmlns:wd="urn:com.workday/bsvc" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:this="urn:this-stylesheet">

    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="/">
        <xsl:copy>
            <Worker>
                <xsl:for-each select="Worker" >
                    <Detail>
                        <EmployeeID><xsl:value-of select="Detail[(PayCode ='Earning')]/EmployeeID"/></EmployeeID>
                        <PayCode><xsl:value-of select="Detail[(PayCode ='Earning')]/PayCode"/></PayCode>
                        <Amount><xsl:value-of select="Detail[(PayCode ='Earning') and (string-length(Amount) > 0)]/Amount"/></Amount>
                    </Detail>
                </xsl:for-each>
            </Worker>
        </xsl:copy>
    </xsl:template>  
</xsl:stylesheet>

期望的输出:

<?xml version="1.0" encoding="UTF-8"?>
<Worker
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:this="this.file/eib"
    xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
    xmlns:tv="java:com.workday.esb.intsys.TypedValue">
   <Detail>
      <EmployeeID>123456</EmployeeID>
      <PayCode>Earning</PayCode>
      <Amount>4243.20</Amount>
   </Detail>
</Worker>

2 个答案:

答案 0 :(得分:1)

我认为没有充分理由保留输出中未使用的命名空间声明。但是如果你真的想拥有它们,为什么不简单地复制它们(作为其父元素的一部分) - 例如:

<强> XSLT

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

<xsl:template match="/Worker">
    <xsl:copy>
        <xsl:copy-of select="Detail[PayCode ='Earning']"/>
    </xsl:copy>
</xsl:template> 

</xsl:stylesheet>

当这个应用于您的输入示例时,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<Worker xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:this="this.file/eib"
        xmlns:is="java:com.workday.esb.intsys.xpath.ParsedIntegrationSystemFunctions"
        xmlns:tv="java:com.workday.esb.intsys.TypedValue">
   <Detail>
      <EmployeeID>123456</EmployeeID>
      <PayCode>Earning</PayCode>
      <Amount>4243.20</Amount>
   </Detail>
</Worker>

演示:http://xsltransform.net/gVhD8Qt

答案 1 :(得分:1)

至少在 XSLT 2.0 (您使用的版本)中,名称空间消失,因为您使用了exclude-result-prefixes属性。

只需删除它,XSLT表中包含的所有名称空间({1}}除外)将按照出现的顺序显示在输出中。

但如果您决定省略所有名称空间,则更容易编写xsl,而不是再次编写它们。