Проблемы генерации SOAP XML с использованием XSLT - PullRequest
0 голосов
/ 18 августа 2011

Я использую XSLT для преобразования некоторого обеспечения XML в запрос SOAP.Но у меня возникают трудности с поиском подхода, который не требует полных выражений XPATH и все еще генерирует действительный SOAP XML.

Вот упрощенная версия обеспечения XML.

<CreateOrder>
    <client_info>
        <name>John Doe</name>
        <address>
            <street1>1211 Lakeview Dr.</street1>
            <city>New York</city>
            <state>NY</state>
            <country>USA</country>
            <zip>12345</zip>
        </address>
    </client_info>
    <subscriber_number>AAANNNDDDD</subscriber_number>
</CreateOrder>

А вотупрощенный XSLT, который я использую.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" />
    <xsl:template match="/">
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
            <soapenv:Header/>
            <soapenv:Body>
                <DirectoryNumber><xsl:value-of select="CreateOrder/subscriber_number"/></DirectoryNumber>
                <Locale>
                    <xsl:choose>
                        <xsl:when test="CreateOrder/client_info/address/country = 'USA'">
                            <xsl:text>English (US)</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>User Defined 1</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </Locale>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
</xsl:stylesheet>

Это генерирует следующий вывод XML - это то, что я ожидал / хочу.[Обратите внимание, что я должен был напечатать это - мой вывод на самом деле представляет собой одну строку без разрывов / отступов.]

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header/>
    <soapenv:Body>
        <DirectoryNumber>
            AAANNNDDDD
        </DirectoryNumber>
        <Locale>
            English (US)
        </Locale>
    </soapenv:Body>
</soapenv:Envelope>

Играя вокруг, кажется, что мне нужно использовать <xsl:template match="/"> длясопоставить весь входной документ, иначе я не получу SOAP XML в выходной файл.Есть ли какой-то другой способ генерирования последовательности нового XML из XSLT?

Но когда присутствует <xsl:template match="/">, я не могу вкладывать другие элементы <xsl:template match=..."> (например, для соответствия "адресу")и поэтому в тестах необходимо использовать полные выражения узла XPATH (например, CreateOrder/client_info/address/country).Это работает, но не особенно элегантно и несколько подвержено ошибкам для более длинного примера из реальной жизни.Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 18 августа 2011

Шаблоны не гнездятся. Вы достигаете того, что хотите, с помощью <xsl:apply-templates.../> в соответствующих местах в ваших шаблонах. В вашем простом примере нет необходимости указывать путь, но в более крупной и сложной таблице стилей может быть много шаблонов многократного использования.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header/>
      <soapenv:Body>
        <DirectoryNumber><xsl:value-of select="CreateOrder/subscriber_number"/></DirectoryNumber>
        <Locale>
          <xsl:apply-templates select="CreateOrder/client_info/address/country"/>
        </Locale>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>

  <xsl:template match="country">
    <xsl:choose>
      <xsl:when test=". = 'USA'">
        <xsl:text>English (US)</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>User Defined 1</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Ключом к пониманию XSLT является осознание того, что оно не процедурное ... ваша таблица стилей НЕ находится под контролем. Вместо этого процессор XSLT проверяет каждый входной тег и затем ищет в таблице стилей соответствующий шаблон. Как только соответствующее правило найдено и применено, обработка для этого тега завершена. Если вы соответствуете /, тогда весь документ используется этим одним шаблоном. Единственный способ вызвать другие шаблоны - через <xsl:apply-templates select="some xpath"/>, который говорит процессору перезапустить процесс сопоставления, используя узлы, выбранные с помощью «some xpath». Первый шаблон в таблице стилей очень часто встречается с /.

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