Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt从xml中删除父节点_Xml_Xslt - Fatal编程技术网

使用xslt从xml中删除父节点

使用xslt从xml中删除父节点,xml,xslt,Xml,Xslt,我需要将一个XML文件转换为另一个XML文件,删除一些父节点 输入Xml: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:autorizacionComprobanteResponse xmlns:ns2="http://ec.gob.sri.ws.autorizacion"> <RespuestaAutorizacionCo

我需要将一个XML文件转换为另一个XML文件,删除一些父节点

输入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>

2.
1.
自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
11
60
在xml输出文件中,我只需要节点“
”而不需要“
”子节点,如下所示:

所需的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>

自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
11
我是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>

这是我使用该xsl获得的xml文件:

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>
2
1.
自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
11
60

我不知道为什么将
xmlns:soap
xmlns:ns2
标记添加到节点
,并且
节点仍然存在。请帮助我解决这个问题,我还需要删除空行,但如果可能,保留缩进。

由于您复制了
自动编辑
节点,因此
mensajes
节点仍然存在。将模板应用于
autorization
的内容时,匹配
mensajes
的空模板将删除此元素。
autorization
的父节点的名称空间被添加到输出中。要删除名称空间,例如,可以编写
autorization
和以下没有名称空间的子节点,如下所示:

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

此模板匹配任何节点,使用当前匹配节点的名称创建元素,并将模板应用于所有属性和子节点,而不添加任何命名空间。
要删除多余的行和空白,可以使用

下面是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>

自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
1.
1.

要在复制时删除名称空间,只需说
copy namespaces='no'
。此外,您可能需要考虑使用<代码>条带空间来删除由转换生成的所有空白。最后,您只需要提到需要排除哪个节点

<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>

自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
1.
1.

我认为这是身份转换的一个细微变化:

<?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>

自动编辑
2.
2015-05-21T14:22:30.764-05:00
普鲁巴斯
11
更新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>

这实际上相当于:

<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的解决方案更加明确,使用“逐步”指令,并在需要时允许更精细的操作。

为什么不使用SOAP客户端呢?感谢您的回答,我正在使用java和xalan 2.7进行处理,您的代码仍然在
节点中包含
xmlns:SOAP
xmlns:ns2
标记。啊,很高兴知道。matthias_h回答的另一个优点是:省略了名称空间。我使用xsltproc评估样式表,但它不包括名称空间。谢谢