在xslt转换中,转换后的xml中不存在值

时间:2019-05-09 10:48:05

标签: xslt

我正在尝试使用xslt转换一个xml,但是我得到了空的xml节点。请让我知道我在想什么。

我的源xml是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:ProcessPartsOrder xmlns="http://www.host.com/ERP/Sales/Entities" xmlns:ns2="http://www.host.com/ERP/Sales/ProcessPartsOrder" xmlns:ns4="http://www.host.com/ERP/Sales/ValueObjects" xmlns:ns3="http://www.host.com/ERP/Sales/Aggregates/PartsOrder">
    <ns2:MessageHeader>
        <CultureCode>en-US</CultureCode>
        <SenderNameCode>S3</SenderNameCode>
        <CreationDateTime>2019-03-19T22:48:16</CreationDateTime>
        <BODID>e27c5244-4f18-4343-a15f-e509b8a75802</BODID>
    </ns2:MessageHeader>    
</ns2:ProcessPartsOrder>

我想转换成以下格式:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder" xmlns:ent="http://www.host.com/ERP/Sales/Entities" xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder" xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
  <soapenv:Header/>
  <soapenv:Body>
    <proc:ProcessPartsOrder>
      <proc:MessageHeader>
        <ent:CultureCode>en-US</ent:CultureCode>
        <ent:SenderNameCode>S3</ent:SenderNameCode>
        <ent:CreationDateTime>2013-01-23T12:41:36-05:00</ent:CreationDateTime>
        <ent:BODID>e27c5244-4f18-4343-a15f-e509b8a75802</ent:BODID>
      </proc:MessageHeader>      
    </proc:ProcessPartsOrder>
  </soapenv:Body>
</soapenv:Envelope>

我的xslt看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns2="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                xmlns:ns3="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                xmlns:ns4="http://www.host.com/ERP/Sales/ValueObjects"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="ns2 ns3 ns4 xs">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/*">
    <soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                      xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                      xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                      xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
      <soapenv:Header/>
      <soapenv:Body>
        <proc:ProcessPartsOrder>
          <proc:MessageHeader>
            <ent:CultureCode>
              <xsl:value-of select="/ns2:ProcessPartsOrder/ns2:MessageHeader/CultureCode"/>
            </ent:CultureCode>
            <ent:SenderNameCode>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/SenderNameCode"/>
            </ent:SenderNameCode>
            <ent:CreationDateTime>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/CreationDateTime"/>
            </ent:CreationDateTime>
            <ent:BODID>
              <xsl:value-of select="ns2:ProcessPartsOrder/ns2:MessageHeader/BODID"/>
            </ent:BODID>
          </proc:MessageHeader>          
        </proc:ProcessPartsOrder>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

所有我都得到了带有空值的预期xml。 我相信我缺少需要帮助的东西。

谢谢。

1 个答案:

答案 0 :(得分:2)

您正在为XPaths赋予值一个不同于源名称空间的名称空间。因此,它们返回空。名称空间本身有所不同。

在您的源代码中,将默认名称空间定义为

xmlns="http://www.host.com/ERP/Sales/Entities"

但是XSLT中的ns2命名空间定义为

xmlns:ns2="http://www.host.com/ERP/Sales/CustomerOrderManagement"

或者当然,您必须在XSLT的XPath表达式中使用相同的名称空间。在那里,您将第一个命名空间定义为proc。因此,将模板更改为以下

<xsl:template match="/">
<soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                  xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                  xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                  xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
  <soapenv:Header/>
  <soapenv:Body>
    <proc:ProcessPartsOrder>
      <proc:MessageHeader>
        <ent:CultureCode>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:CultureCode"/>
        </ent:CultureCode>
        <ent:SenderNameCode>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:SenderNameCode"/>
        </ent:SenderNameCode>
        <ent:CreationDateTime>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:CreationDateTime"/>
        </ent:CreationDateTime>
        <ent:BODID>
          <xsl:value-of select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:BODID"/>
        </ent:BODID>
      </proc:MessageHeader>          
    </proc:ProcessPartsOrder>
  </soapenv:Body>
 </soapenv:Envelope>
</xsl:template>

或者,另一种方法,您可以添加名称空间

xmlns:ent="http://www.host.com/ERP/Sales/Entities"

添加到样式表元素,并为ent:元素添加修改后的身份模板,该模板将更改每个复制元素的命名空间:

<xsl:template match="ent:*">
  <xsl:element name="ent:{local-name()}" namespace="http://www.host.com/ERP/Sales/Entities">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

然后您的主模板可以简化为

<xsl:template match="/">
    <soapenv:Envelope xmlns="http://www.host.com/ERP/Sales/CustomerOrderManagement"
                      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:proc="http://www.host.com/ERP/Sales/ProcessPartsOrder"
                      xmlns:ent="http://www.host.com/ERP/Sales/Entities"
                      xmlns:par="http://www.host.com/ERP/Sales/Aggregates/PartsOrder"
                      xmlns:val="http://www.host.com/ERP/Sales/ValueObjects">
      <soapenv:Header/>
      <soapenv:Body>
        <proc:ProcessPartsOrder>
          <proc:MessageHeader>
            <xsl:apply-templates select="/proc:ProcessPartsOrder/proc:MessageHeader/ent:*"/>
          </proc:MessageHeader>          
        </proc:ProcessPartsOrder>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>
</xsl:stylesheet>

要复制属性,请添加未修改的身份模板