从XSLT删除XML父节点(Remove parent nodes from xml with xs

2019-10-23 04:54发布

我需要一个XML文件转换到另一个XML文件中删除一些父节点。

INPTUT XML:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:autorizacionComprobanteResponse xmlns:ns2="http://ec.gob.sri.ws.autorizacion">
<RespuestaAutorizacionComprobante>
  <claveAccesoConsultada>2</claveAccesoConsultada>
  <numeroComprobantes>1</numeroComprobantes>
  <autorizaciones>
    <autorizacion>
      <estado>AUTORIZADO</estado>
      <numeroAutorizacion>2</numeroAutorizacion>
      <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
      <ambiente>PRUEBAS</ambiente>
      <comprobante>
        <factura id="comprobante" version="1.0.0">
          <infoTributaria>
            <ambiente>1</ambiente><tipoEmision>1</tipoEmision>
          </infoTributaria>
        </factura>
      </comprobante>
      <mensajes>
        <mensaje>
          <identificador>60</identificador>
        </mensaje>
      </mensajes>
    </autorizacion>
  </autorizaciones>
</RespuestaAutorizacionComprobante>
</ns2:autorizacionComprobanteResponse>
</soap:Body>
</soap:Envelope>

在XML输出文件我只需要节点“ <autorizacion> ”无“ <mensajes>像这样”子节点:

期望的XML输出:

<autorizacion>
    <estado>AUTORIZADO</estado>
    <numeroAutorizacion>2</numeroAutorizacion>
    <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
    <ambiente>PRUEBAS</ambiente>
    <comprobante>
        <factura id="comprobante" version="1.0.0">
            <infoTributaria><ambiente>1</ambiente><tipoEmision>1</tipoEmision>
        </factura>
    </comprobante>
</autorizacion>

我是新来的XSLT,但我已经尝试了几个例子,该代码获取最接近的输出:

XSL文件:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="autorizacion">
        <xsl:copy-of select="." />
    </xsl:template>
    <xsl:template match="mensajes"/>
</xsl:stylesheet>

这是XML文件,我与XSL得到:

2
1
    <autorizacion xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://ec.gob.sri.ws.autorizacion">
        <estado>AUTORIZADO</estado>
        <numeroAutorizacion>2</numeroAutorizacion>
        <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
        <ambiente>PRUEBAS</ambiente>
        <comprobante>
            <factura id="comprobante" version="1.0.0">
                <infoTributaria><ambiente>1</ambiente><tipoEmision>1</tipoEmision>
            </factura>
        </comprobante>
        <mensajes>
            <mensaje>
                <identificador>60</identificador>
            </mensaje>
        </mensajes>
    </autorizacion>

我不知道为什么xmlns:soapxmlns:ns2标签添加到节点<autorizacion>也是<mensajes>节点仍然存在。 请帮我解决这个问题,我还需要删除空行,但保持缩进如果可能的话。

Answer 1:

mensajes节点北京时间仍然存在,因为你复制autorizacion节点。 当应用模板的内容autorizacion ,空模板匹配mensajes将删除此元素。
的父节点的命名空间autorizacion被添加到输出中。 要删除的命名空间,它可能例如写autorizacion没有这样的命名空间和下面的子节点:

<xsl:template match="*">
  <xsl:element name="{local-name(.)}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>

该模板匹配任何节点,与当前匹配的节点的名称创建一个元素,并应用模板的所有属性和子节点,无需添加任何命名空间。
以除去empy线和空白,可以使用<xsl:strip-space elements="*"/>

下面的XSLT

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
  <xsl:template match="/" >
    <xsl:apply-templates select="//autorizacion" />
  </xsl:template>
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="mensajes"/>
</xsl:stylesheet>

当应用到你的输入XML产生输出

<autorizacion>
  <estado>AUTORIZADO</estado>
  <numeroAutorizacion>2</numeroAutorizacion>
  <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
  <ambiente>PRUEBAS</ambiente>
  <comprobante>
  <factura id="comprobante" version="1.0.0">
     <infoTributaria>
        <ambiente>1</ambiente>
        <tipoEmision>1</tipoEmision>
     </infoTributaria>
    </factura>
  </comprobante>
</autorizacion>


Answer 2:

对于复印时的命名空间中移除你只需要说copy-namespaces='no' 。 此外,您可能要考虑使用strip-space删除所有通过变换产生的空格。 最后,你只需要一提的,你需要排除的节点。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:ns2="http://ec.gob.sri.ws.autorizacion"
   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

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


<xsl:template match="autorizacion">  
    <xsl:copy copy-namespaces='no'>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>


<xsl:template match="@*|node()[not(self::mensajes) and (ancestor::autorizacion)]">
    <xsl:copy copy-namespaces='no'>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>


 <xsl:template match="mensajes|claveAccesoConsultada|numeroComprobantes"/>

 </xsl:stylesheet>

输出是:

<autorizacion>
   <estado>AUTORIZADO</estado>
   <numeroAutorizacion>2</numeroAutorizacion>
   <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
   <ambiente>PRUEBAS</ambiente>
   <comprobante>
      <factura id="comprobante" version="1.0.0">
         <infoTributaria>
            <ambiente>1</ambiente>
            <tipoEmision>1</tipoEmision>
         </infoTributaria>
      </factura>
   </comprobante>
</autorizacion>


Answer 3:

我看到这对身份的轻微变化变换:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <xsl:apply-templates select="//autorizacion"/>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="mensajes"/>
</xsl:stylesheet>

我不知道这是如何栈对这里其他的答案,这都看身份变换十岁上下。 这里的输出我得到:

<autorizacion>
  <estado>AUTORIZADO</estado>
  <numeroAutorizacion>2</numeroAutorizacion>
  <fechaAutorizacion>2015-05-21T14:22:30.764-05:00</fechaAutorizacion>
  <ambiente>PRUEBAS</ambiente>
  <comprobante>
    <factura id="comprobante" version="1.0.0">
      <infoTributaria>
        <ambiente>1</ambiente><tipoEmision>1</tipoEmision>
      </infoTributaria>
    </factura>
  </comprobante>    
</autorizacion>

更新1

我认为matthias_h的回答和我是通过和大型相同。

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="node()|@*"/>
  </xsl:element>
</xsl:template>
<xsl:template match="@*">
  <xsl:attribute name="{local-name(.)}">
    <xsl:value-of select="."/>
  </xsl:attribute>
</xsl:template>

实际上等同于:

<xsl:template match="node()">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="@*">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
  </xsl:copy>
</xsl:template>

这实际上等同于:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

matthias_h的解决方案是更加明确,用“一步一步”的指示,并允许更多的技巧如果需要的话。



文章来源: Remove parent nodes from xml with xslt
标签: xml xslt