Отказаться от прав на результаты XML с помощью XSLT - PullRequest
2 голосов
/ 17 декабря 2011

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

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
  <env:Header />
  <env:Body>
    <ns1:searchResponse xmlns:ns1='http://url.to.namespace' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
      <ns1:result>&lt;?xml version="1.0"?&gt;&lt;results count="201" returned="201" code="200" msg="successful"&gt;&lt;result order="0"&gt;&lt;dirkey&gt;DK886shn3525&lt;/dirkey&gt;&lt;eid&gt;smith&lt;/eid&gt;&lt;email&gt;smith@me.edu&lt;/email&gt;&lt;fn&gt;Smith&lt;/fn&gt;&lt;ln&gt;Bob&lt;/ln&gt;&lt;wid&gt;859589157&lt;/wid&gt;&lt;score&gt;70&lt;/score&gt;&lt;/result&gt;&lt;result order="1"&gt;&lt;dirkey&gt;DK547fjx6702&lt;/dirkey&gt;&lt;eid&gt;james31&lt;/eid&gt;&lt;email&gt;ta@me.edu&lt;/email&gt;&lt;fn&gt;Tim&lt;/fn&gt;&lt;ln&gt;Allen&lt;/ln&gt;&lt;stu&gt;&lt;lvl&gt;Senior&lt;/lvl&gt;&lt;plans&gt;&lt;plan&gt;Technology Management-B&lt;/plan&gt;&lt;/plans&gt;&lt;contacts&gt;&lt;contact type="permanent"&gt;&lt;city&gt;Salina&lt;/city&gt;&lt;phone&gt;(123) 456-7890&lt;/phone&gt;&lt;postal&gt;67401&lt;/postal&gt;&lt;street1&gt;1111 Main Ln&lt;/street1&gt;&lt;state&gt;KS&lt;/state&gt;&lt;/contact&gt;&lt;/contacts&gt;&lt;/stu&gt;&lt;wid&gt;2222222222&lt;/wid&gt;&lt;score&gt;20&lt;/score&gt;&lt;/result&gt;</ns1:result>
    </ns1:searchResponse>
  </env:Body>
</env:Envelope>

Меня больше всего интересуют данные, содержащиеся в элементе <ns1:result>.Хотя это может иметь смысл в мире HTML, мне нужно <ns1:result> text как XML .Заинтригованный возможностью сделать это через XSL, я создал следующую таблицу стилей:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="http://url.to.namespace"
  exclude-result-prefixes="env ns1">

  <xsl:output omit-xml-declaration="yes" indent="yes" method="text" />
  <xsl:strip-space elements="*"/>

  <!-- Template #1 - Identity Transform -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Template #2 - for all text() nodes, disable output escaping -->
  <xsl:template match="text()">
    <xsl:copy-of select="." disable-output-escaping="yes" />
  </xsl:template>

</xsl:stylesheet>

... которая технически производит то, что я хочу:

<?xml version="1.0"?>
<results count="201" returned="201" code="200" msg="successful">
  <result order="0">
    <dirkey>DK886shn3525</dirkey>
    <eid>smith</eid>
    <email>smith@me.edu</email>
    <fn>Bob</fn>
    <ln>Smith</ln>
    <wid>859589157</wid>
    <score>70</score>
  </result>
  <result order="1">
    <dirkey>DK547fjx6702</dirkey>
    <eid>ta</eid>
    <email>ta@me.edu</email>
    <fn>Tim</fn>
    <ln>Allen</ln>
    <stu>
      <lvl>Senior</lvl>
      <plans>
        <plan>Technology Management-B</plan>
      </plans>
      <contacts>
        <contact type="permanent">
          <city>Salina</city>
          <phone>(123) 456-7890</phone>
          <postal>67401</postal>
          <street1>1111 Main Ln</street1>
          <state>KS</state>
        </contact>
      </contacts>
    </stu>
    <wid>2222222222</wid>
    <score>20</score>
  </result>
</results>

Тем не менее, я слышал, что DOE является признаком отчаявшегося человека.Действительно, когда я пытаюсь запустить этот XSLT через наше приложение (которое предназначено для преобразования XML перед передачей его в шаблонизатор), оно не работает.Я предполагаю, что DOE не реализован в нашем конкретном синтаксическом анализаторе XSL ...

Итак, вот главный вопрос: есть ли способ в XSLT 1.0, чтобы освободить эти объекты без использования специфической для парсера тактики, такой как DOE?Моя единственная мысль - создать метод, который переводит определенные экранированные символы (например, &gt;) в их буквальные аналоги (>) ... но я не совсем уверен, как бы я поступил в этом направлении.

Как всегда, я ценю вашу помощь.

PS Пожалуйста, не беспокойтесь, рассказывайте мне, как отвратительны эти результаты или как они исказили структуру своего документа;мы уже пытались заставить их изменить это, и это не вариант.(

1 Ответ

1 голос
/ 17 декабря 2011

Итак, вот главный вопрос: есть ли способ в XSLT 1.0, чтобы убрать эти объекты без использования специфической для парсера тактики, такой как DOE?Моя единственная мысль - создать метод, который переводит определенные экранированные символы (например,>) в их буквальные аналоги (>) ... но я не совсем уверен, как бы я поступил об этом.

Не существует чистого способа XSLT для восстановления уничтоженной разметки - до XSLT 3.0 (все еще рабочий проект W3C), который будет сохранять стандартную функцию parse-xml()

Пока у вас не будет доступен XSLT 3.0, безопасный способ восстановления уничтоженной разметки - это вызов функции расширения с аналогичной сигнатурой , которую вы должны написать сами.

Эта функция расширения попытается проанализировать свой строковый аргумент в экземпляре XmlDocument и в случае успеха вернет результат.

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