基于对等节点复制XML节点

时间:2017-01-20 11:21:48

标签: xml xslt xpath

我有一个源XML

   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <urn:LookupRecords xmlns:urn="urn:RedIron.RetailRepository.Services.SearchService" xmlns:a="urn:RedIron.RetailRepository.Core" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <urn:query>
        <a:Headers>
          <a:SearchHeader>
            <a:Name>MAX_RESULTS</a:Name>
            <a:ProviderGuid>00000000-0000-0000-0000-000000000000</a:ProviderGuid>
            <a:Value>10</a:Value>
          </a:SearchHeader>
          <a:SearchHeader>
            <a:Name>CASHIER</a:Name>
            <a:Value>1706</a:Value>
          </a:SearchHeader>
          <a:SearchHeader>
            <a:Name>RECEIPT_LOOKUP</a:Name>
            <a:Value>CustomerReceipt</a:Value>
          </a:SearchHeader>
        </a:Headers>
        <a:Params>
          <arr:KeyValueOfguidArrayOfQueryParametertmL6yAXy>
            <arr:Key>{4de38819-43bf-4333-a17b-049ec32703c3}</arr:Key>
            <arr:Value>
              <a:QueryParameter>
                <a:Name>TRAINING_MODE</a:Name>
                <a:Value>FALSE</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>STORE</a:Name>
                <a:Value>121</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>REGISTER</a:Name>
                <a:Value>2</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>TRANSACTION_NUMBER</a:Name>
                <a:Value>1843</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>TRANSACTION_DATE_YEAR</a:Name>
                <a:Value>2016</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>TRANSACTION_DATE_MONTH</a:Name>
                <a:Value>12</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>TRANSACTION_DATE_DAY</a:Name>
                <a:Value>20</a:Value>
              </a:QueryParameter>
              <a:QueryParameter>
                <a:Name>CONCEPT</a:Name>
                <a:Value>WS</a:Value>
              </a:QueryParameter>
            </arr:Value>
          </arr:KeyValueOfguidArrayOfQueryParametertmL6yAXy>
        </a:Params>
      </urn:query>
    </urn:LookupRecords>
  </soapenv:Body>
</soapenv:Envelope>

我希望将结果XML作为

<Lookup xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" content="sample string 1" type="sample string 2" pageIndex="sample string 3" pageSize="sample string 4" tranSortOrder="sample string 5">
  <RequestData TrainingModeFlag="False" Store="sample string 1" Operator="sample string 2" Terminal="sample string 3">
    <TRANSACTION_DATE_YEAR>2016</TRANSACTION_DATE_YEAR>
    <TRANSACTION_DATE_MONTH>sample string 15</TRANSACTION_DATE_MONTH>
    <TransactionNumber>sample string 17</TransactionNumber>
  </RequestData>
</Lookup>

我正在使用XSLT与

相同
<xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
     xmlns:a="urn:RedIron.RetailRepository.Core"
      version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match = "a:QueryParameter" >  
<xsl:apply-templates select="a:QueryParameter[a:Name='TRANSACTION_NUMBER']/a:Value"/>
</xsl:template>

<xsl:template match="/">
<Lookup tranSortOrder="sample string 5" 
pageSize="sample string 4" 
pageIndex="sample string 3" 
type="sample string 2" 
content="sample string 1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<RequestData Terminal="sample string 3" 
Operator="sample string 2" 
Store="sample string 1" 
TrainingModeFlag="False">

<OrderNumber>    
</OrderNumber>
<TransactionNumber>
  <xsl:apply-templates />  
</TransactionNumber>
</RequestData>
</Lookup>    
</xsl:template>
</xsl:stylesheet>

使用Xpath作为:QueryParameter [a:名称=&#39; TRANSACTION_NUMBER&#39;] / a:值

我没有得到理想的输出(这是1843年)

请告诉我哪里错了?

1 个答案:

答案 0 :(得分:0)

你应该纠正的第一件事就是你的XML。

请注意,您使用 a arr 的命名空间,但未能在主( Envelope )标记中指定它们。

所以我将标题更改为:

<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:a="urn:RedIron.RetailRepository.Core"
    xmlns:arr="urn:dummy">

我也在<a:QueryParameter>之后插入了<arr:Value>(显然你错过了这个细节)。

现在让我们转到你的XSLT。

一个变化是apply-templates(最后)应限制为//arr:Value。 否则,您还可以获得其他元素的所有文本节点。

我在模板匹配QueryParameter中也进行了重大更改。

请注意每个select子句的内容:

a:QueryParameter[a:Name/text()='...']/a:Value

实际上意味着:

  • 带子QueryParameter节点 - a:QueryParameter
  • 这样 - [...]
  • 它有a:Name子节点,
  • ,其中包含文本子节点 - /text()
  • 等于字符串='...'
  • 并从此(QueryParameter)节点获取子a:Value的内容。

您的错误是当您想要将节点的内容与某个值进行比较时 在谓词中,您必须使用text()来引用此节点的文本内容。

不需要,例如在value-of

下面你已经改变了我的XSLT。

另请注意,因为我引用了arr命名空间,所以我必须将其添加到stylesheet标记。

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:a="urn:RedIron.RetailRepository.Core"
    xmlns:arr="urn:dummy"
    version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="arr:Value" >
  <TRANSACTION_DATE_YEAR>
    <xsl:value-of
      select="a:QueryParameter[a:Name/text()='TRANSACTION_DATE_YEAR']/a:Value"/>
  </TRANSACTION_DATE_YEAR>
  <TRANSACTION_DATE_MONTH>
    <xsl:value-of
      select="a:QueryParameter[a:Name/text()='TRANSACTION_DATE_MONTH']/a:Value"/>
  </TRANSACTION_DATE_MONTH>
  <TransactionNumber>
    <xsl:value-of
      select="a:QueryParameter[a:Name/text()='TRANSACTION_NUMBER']/a:Value"/>
  </TransactionNumber>
</xsl:template>

<xsl:template match="/">
<Lookup tranSortOrder="sample string 5" pageSize="sample string 4" 
pageIndex="sample string 3" type="sample string 2" content="sample string 1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <RequestData Terminal="sample string 3" Operator="sample string 2" 
    Store="sample string 1" TrainingModeFlag="False">
    <xsl:apply-templates select="//arr:Value"/>
  </RequestData>
</Lookup>    
</xsl:template>
</xsl:stylesheet>