Значения отсутствуют в преобразованном xml в преобразовании xslt - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь преобразовать один xml с помощью xslt, но получаю пустые узлы 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 Ответ

2 голосов
/ 09 мая 2019

Вы присваивали значениям XPath значения, отличные от пространства источника. Следовательно они возвращаются пустыми. Само пространство имен отличается.

В вашем источнике вы определяете пространство имен по умолчанию как

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

Но пространство имен ns2 в XSLT определяется как

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

Или, конечно, вы должны использовать то же пространство имен в выражении XPath XSLT. Там вы определили первое пространство имен как 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>

Чтобы также скопировать атрибуты, добавьте неизмененный шаблон идентификации .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...