[英]Remove parent nodes from xml with 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">
<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>
这是我通过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>
我不知道为什么将xmlns:soap
和xmlns:ns2
标记添加到节点<autorizacion>
且<mensajes>
节点仍然存在。 请帮助我解决这个问题,如果可能的话,我还需要删除空行,但要保留缩进。
mensajes
节点仍然存在,因为您复制了autorizacion
节点。 当应用模板的内容autorizacion
,空模板匹配mensajes
将删除此元素。
autorizacion
的父节点的名称空间将添加到输出中。 要删除名称空间,例如可以编写autorizacion
并跟随没有该名称空间的子节点,如下所示:
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
该模板与任何节点匹配,使用当前匹配的节点的名称创建一个元素,并将模板应用于所有属性和子节点,而无需添加任何名称空间。
要删除空行和空格,可以使用<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>
要在复制时删除名称空间,您只需要说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>
我在身份转换上看到了一些细微变化:
<?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>
我不知道这与这里的其他答案如何叠加,这些答案看起来都像是身份转换的ish。 这是我得到的输出:
<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的解决方案使用“逐步”指令更加明确,并在需要时提供更多技巧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.