使用XSLT取消对XML结果的授权

时间:2011-12-17 18:23:58

标签: xslt soap

我陷入了两难境地。在特定的应用程序中,我从SOAP请求接收XML结果,如下所示:

<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是一个绝望的个体的标志。实际上,当我尝试通过我们的应用程序(在将其传递给模板引擎之前将其转换为XML)运行此XSLT时,它不起作用。我猜测DOE没有在我们特定的XSL解析器中实现......

所以,这是最终的问题:在XSLT 1.0中是否有一种方法可以在不使用像DOE这样的特定于解析器的策略的情况下解除这些实体的问题?我的一个想法是构建一个方法,将某些转义字符(例如&gt;)转换为它们的文字对应物(>)......但我不完全确定我是如何去做的。

与往常一样,感谢您的协助。

P.S。拜托,请不要告诉我这个输出是多么令人厌恶,或者他们如何破坏了他们的文档结构;我们已经试图让他们改变它,这不是一个选择。 :(

1 个答案:

答案 0 :(得分:1)

  

所以,这是最终的问题:XSLT 1.0中有没有办法   unescape这些实体不使用特定于解析器的策略   DOE?我的想法是构建一种翻译某些方法的方法   将字符(例如,&gt;)转义为字面对应字符   (&gt;)......但我不完全确定我会怎么做。

没有一种纯XSLT方法来重建被破坏的标记 - 直到XSLT 3.0(仍然是W3C工作草案)将xave标准函数 parse-xml()

在您使用XSLT 3.0之前,重建已销毁标记的安全方法是调用具有类似签名的扩展函数,您必须自己编写。

此扩展函数将尝试将其字符串参数解析为XmlDocument的实例,如果成功,则返回结果。