简体   繁体   English

如何将String xml转换为XML节点XSLT

[英]How to convert a String xml into a XML node XSLT

I´m consuming the Banxico Web Services and it returns a string, inside that string there is the XML. 我正在使用Banxico Web服务,它返回一个字符串,该字符串中有XML。

What I really need is to extract the next part using XSLT or XPath. 我真正需要的是使用XSLT或XPath提取下一部分。

How can do it using XSLT or Xpath? 如何使用XSLT或Xpath?

Pesos por dólar EUA Tipo de cambio para solventar obligaciones denominadas en moneda extranjera Fecha de determinación (FIX)" IDSERIE="SF43718" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="PesoxDoll"> Pesos por dular EUA Tipo de cambio parasolarable obligaciones denominadas en moneda extranjera Fecha dedeterminación(FIX)“ IDSERIE =” SF43718“ BANXICO_FREQ =” Dia“ BANXICO_FIGURE_TYPE =” TipoCambio“ BANXICO_UNIT_TYPE =” PesoxDoll“>

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Header>
      <X-OPNET-Transaction-Trace:X-OPNET-Transaction-Trace soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0" xsi:type="soapenc:string" xmlns:X-OPNET-Transaction-Trace="http://opnet.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">pid=4468,requestid=4d0ce60a-c92f-441e-87b1-4c6f12b26574</X-OPNET-Transaction-Trace:X-OPNET-Transaction-Trace>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:tiposDeCambioBanxicoResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://ws.dgie.banxico.org.mx">
         <result xsi:type="xsd:string"><![CDATA[<?xml version="1.0" encoding="ISO-8859-1"?>
<CompactData xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/message"
xmlns:bm="http://www.banxico.org.mx/structure/key_families/dgie/sie/series/compact"
xmlns:compact="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/compact"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/message SDMXMessage.xsd
http://www.banxico.org.mx/structure/key_families/dgie/sie/series/compact BANXICO_DGIE_SIE_Compact.xsd
http://www.SDMX.org/resources/SDMXML/schemas/v1_0/compact SDMXCompactData.xsd" >
    <Header>
        <ID>TIPOSDECAMBIO</ID>
        <Test>false</Test>
        <Truncated>false</Truncated>
        <Name xml:lang="sp">Tipos de Cambio</Name>
        <Prepared>2016-12-15 12:26:37.766</Prepared>
        <Sender id="BANXICO">
            <Name xml:lang="sp">Banco de México</Name>
            <Contact>
            <Name xml:lang="sp">Subgerencia de Desarrollo de Sistemas</Name>
            <Telephone>(01 55)52372678</Telephone>
            </Contact>
        </Sender>
        <DataSetAction>Update</DataSetAction>
        <Extracted>2016-12-15 12:26:37.766</Extracted>
    </Header>
    <bm:DataSet>
        <bm:SiblingGroup BANXICO_FREQ="Dia" TIME_FORMAT="P1D"/>
        <bm:Series TITULO="Tipo de cambio pesos por dólar E.U.A. Tipo de cambio para solventar obligaciones denominadas en moneda extranjera Fecha de liquidación" IDSERIE="SF60653" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="PesoxDoll">
            <bm:Obs TIME_PERIOD="2016-12-15" OBS_VALUE="20.2567"/>
        </bm:Series>
        <bm:Series TITULO="Tipo de cambio                                          Pesos por dólar E.U.A. Tipo de cambio para solventar obligaciones denominadas en moneda extranjera Fecha de determinación (FIX)" IDSERIE="SF43718" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="PesoxDoll">
            <bm:Obs TIME_PERIOD="2016-12-15" OBS_VALUE="20.5973"/>
        </bm:Series>
        <bm:Series TITULO="Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Euro" IDSERIE="SF46410" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="Peso">
            <bm:Obs TIME_PERIOD="2016-12-14" OBS_VALUE="21.535"/>
        </bm:Series>
        <bm:Series TITULO="Cotización de la divisa Respecto al peso mexicano Dólar Canadiense" IDSERIE="SF60632" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="Peso">
            <bm:Obs TIME_PERIOD="2016-12-14" OBS_VALUE="15.4178"/>
        </bm:Series>
        <bm:Series TITULO="Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Yen japonés" IDSERIE="SF46406" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="Peso">
            <bm:Obs TIME_PERIOD="2016-12-14" OBS_VALUE="0.176"/>
        </bm:Series>
        <bm:Series TITULO="Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Libra esterlina" IDSERIE="SF46407" BANXICO_FREQ="Dia" BANXICO_FIGURE_TYPE="TipoCambio" BANXICO_UNIT_TYPE="Peso">
            <bm:Obs TIME_PERIOD="2016-12-14" OBS_VALUE="25.5806"/>
        </bm:Series>
    </bm:DataSet>
</CompactData>]]></result>
      </ns1:tiposDeCambioBanxicoResponse>
   </soapenv:Body>
</soapenv:Envelope>

With that response I build a xsd schema. 通过该响应,我构建了一个xsd模式。

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.banxico.org.mx/structure/key_families/dgie/sie/series/compact" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="DataSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="SiblingGroup">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute type="xs:string" name="BANXICO_FREQ"/>
                <xs:attribute type="xs:duration" name="TIME_FORMAT"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
        <xs:element name="Series" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Obs">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:date" name="TIME_PERIOD" use="optional"/>
                      <xs:attribute type="xs:float" name="OBS_VALUE" use="optional"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute type="xs:string" name="TITULO" use="optional"/>
            <xs:attribute type="xs:string" name="IDSERIE" use="optional"/>
            <xs:attribute type="xs:string" name="BANXICO_FREQ" use="optional"/>
            <xs:attribute type="xs:string" name="BANXICO_FIGURE_TYPE" use="optional"/>
            <xs:attribute type="xs:string" name="BANXICO_UNIT_TYPE" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

To just run an XSL transformation to extract the information you want, you don't need to generate a schema. 只需运行XSL转换以提取所需的信息,就无需生成模式。

If you can use XPath 3 functions, you can do all of this in one pass: XPath 3 includes a function to parse a string and turn it into a logical XML tree, allowing you to then run XPath expressions against that. 如果可以使用XPath 3函数,则可以一次性完成所有这些操作:XPath 3包括一个函数,该函数可以解析字符串并将其转换为逻辑XML树,然后允许您针对该字符串运行XPath表达式。

If you can't use XPath 3 functions, then you'll need to do this in two passes: export just the <result> text content (the XML response that you want to further process) to a separate file, and then load that file and run another transform on that to extract what you want. 如果您不能使用XPath 3函数,则需要分两次进行:将<result>文本内容(您要进一步处理的XML响应)仅导出到单独的文件,然后加载该文件。文件并对其进行另一次转换以提取所需内容。

Here's a quick-and-dirty example of how to process this in one pass using XPath 3. 这是一个简单的示例,说明了如何使用XPath 3一次性处理此问题。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

    <!-- Start at the document node / and set up the outermost element -->
    <xsl:template match="/">
        <!-- Change this element name to whatever makes sense for you -->
        <BanxicoReply>
            <!-- The input file only has one "result", 
                and that's all we want, so grab it -->
            <xsl:apply-templates select="//result"/>
        </BanxicoReply>
    </xsl:template>

    <xsl:template match="result">
        <!-- Parse the CDATA content to turn it into XML -->
        <xsl:variable name="contained-xml" select="parse-xml(./text())"/>

        <!-- Do what you need to here.
            This example just plucks out the one chunk
            you identified at the top of your post. 

            Note the "*:Series" shorthand: this matches
            any "Series" element in any namespace.  This 
            is an admittedly sloppy shortcut, which could
            be dangerous in other contexts - but here, in
            this one file, it's safe, and this avoids the 
            need for us to explicitly declare the "bm:" 
            namespace prefix in this XSL. -->
        <xsl:copy-of select="$contained-xml//*:Series[@IDSERIE='SF43718']"/>
    </xsl:template>

    <!-- Suppress output of all other elements -->
    <xsl:template match="*"/>

</xsl:stylesheet>

Using your XML above as the input, this XSL produces the following result (indented for easier human legibility): 使用上面的XML作为输入,此XSL产生以下结果(缩进以便于人类阅读):

<?xml version="1.0" encoding="UTF-8"?>
<BanxicoReply>
    <bm:Series xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/message" 
        xmlns:bm="http://www.banxico.org.mx/structure/key_families/dgie/sie/series/compact" 
        xmlns:compact="http://www.SDMX.org/resources/SDMXML/schemas/v1_0/compact" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        TITULO="Tipo de cambio                                          Pesos por dólar E.U.A. Tipo de cambio para solventar obligaciones denominadas en moneda extranjera Fecha de determinación (FIX)" 
        IDSERIE="SF43718" 
        BANXICO_FREQ="Dia" 
        BANXICO_FIGURE_TYPE="TipoCambio" 
        BANXICO_UNIT_TYPE="PesoxDoll">
        <bm:Obs TIME_PERIOD="2016-12-15" OBS_VALUE="20.5973"/>
    </bm:Series>
</BanxicoReply>

我建议使用JSON API https://www.banxico.org.mx/SieAPIRest,而不要使用旧的肥皂服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM