我需要将一个XML文件转换为另一个XML文件,删除一些父节点。
INPTUT Xml:
student
在xml输出文件中,我只需要节点&#34; <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>
&#34;没有&#34; <autorizacion>
&#34;像这样的子节点:
所需的xml输出:
<mensajes>
我是xslt的新手,但我尝试了几个示例,此代码获得最接近的输出:
Xsl文件:
<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>
这是我用xsl获得的xml文件:
<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>
我不知道为什么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>
节点仍然存在。请帮我解决这个问题,我还需要删除空行,但如果可能的话还要保留缩进。
答案 0 :(得分: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>
答案 1 :(得分:1)
要在复制时删除命名空间,只需要说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>
答案 2 :(得分:0)
我认为身份变换略有不同:
<?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的解决方案更明确,使用&#34;逐步&#34;指令,并在需要时允许更精细。