[英]XSLT to change namespace prefix
我正在尝试将属性转换为元素,与此同时,我想更改 XML 代码的命名空间前缀。 XML 代码:
<lm:GetInvoiceList xmlns:lm="http://www.w3.org">
<lm:Response>
<lm:Bill>
<lm:BillStatusCode typecode="1">type description</lm:BillStatusCode>
<lm:EBillProcessStatusCode typecode="2">type description</lm:EBillProcessStatusCode>
<lm:BillCycleCode typecode="1">type description</lm:BillCycleCode>
<lm:BillActivityCode typecode="3">type description</lm:BillActivityCode>
<lm:ToDate>...</lm:ToDate>
</lm:Bill>
</lm:Response>
</lm:GetInvoiceList>
我有这个 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="node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@*]">
<xsl:copy>
<xsl:element name="ns:{name()}">
<xsl:apply-templates select="node()"/>
</xsl:element>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*|*[@*]">
<xsl:element name="ns:{local-name()}" namespace="http://my.ns.uri">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="ns:{name()}" namespace="http://my.ns.uri">
<xsl:copy-of select="namespace::*"/>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但我没有得到所需的输出。
预期输出:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillStatusCode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
<ns:typecode>1</ns:typecode>
</ns:BillStatusCode>
<ns:EBillProcessStatusCode>
<ns:EBillProcessStatusCode>type description</ns:EBillProcessStatusCode>
<ns:typecode>2</ns:typecode>
</ns:EBillProcessStatusCode>
<ns:BillCycleCode>
<ns:BillCycleCode>type description</ns:BillCycleCode>
<ns:typecode>1</ns:typecode>
</ns:BillCycleCode>
<ns:BillActivityCode>
<ns:BillActivityCode>type description</ns:BillActivityCode>
<ns:typecode>3</ns:typecode>
</ns:BillActivityCode>
<ns:ToDate>...</ns:ToDate>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
实际输出:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillStatusCode>
<ns:typecode>1</ns:typecode>type description</ns:BillStatusCode>
<ns:EBillProcessStatusCode>
<ns:typecode>2</ns:typecode>type description</ns:EBillProcessStatusCode>
<ns:BillCycleCode>
<ns:typecode>1</ns:typecode>type description</ns:BillCycleCode>
<ns:BillActivityCode>
<ns:typecode>3</ns:typecode>type description</ns:BillActivityCode>
<ns:ToDate>...</ns:ToDate>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
将不胜感激任何帮助!
鉴于您在评论中的澄清,我建议:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://my.ns.uri">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[@*]">
<xsl:element name="ns:{local-name()}">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
<xsl:apply-templates select="@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="ns:{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
有什么不同?
当应用于以下示例输入时:
XML
<lm:GetInvoiceList xmlns:lm="http://www.w3.org">
<lm:Response>
<lm:Bill>
<lm:BillPropertyA subPropertyA="first subproperty">first property</lm:BillPropertyA>
<lm:BillPropertyB subPropertyB="second subproperty"/>
<lm:BillPropertyC>second property</lm:BillPropertyC>
</lm:Bill>
</lm:Response>
</lm:GetInvoiceList>
结果将是:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillPropertyA>
<ns:BillPropertyA>first property</ns:BillPropertyA>
<ns:subPropertyA>first subproperty</ns:subPropertyA>
</ns:BillPropertyA>
<ns:BillPropertyB>
<ns:BillPropertyB/>
<ns:subPropertyB>second subproperty</ns:subPropertyB>
</ns:BillPropertyB>
<ns:BillPropertyC>second property</ns:BillPropertyC>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
与:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillPropertyA>
<ns:subPropertyA>first subproperty</ns:subPropertyA>
<ns:BillPropertyA>first property</ns:BillPropertyA>
</ns:BillPropertyA>
<ns:BillPropertyB>
<ns:subPropertyB>second subproperty</ns:subPropertyB>
</ns:BillPropertyB>
<ns:BillPropertyC>
<ns:BillPropertyA>second property</ns:BillPropertyA>
</ns:BillPropertyC>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
它将“第二个属性”文本节点错误地放置在ns:BillPropertyA
另一个实例下,并使其成为ns:BillPropertyA
的子ns:BillPropertyC
。
注意事项:
如果要更改节点的命名空间,则不能使用xsl:copy
,因为这也会复制现有的命名空间;
您可以(并且应该)声明命名空间一次,然后在必要时使用已经存在的绑定。
试试这个 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:element name="ns:{local-name()}" namespace="http://my.ns.uri">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:element name="ns:{local-name(../../*)}" namespace="http://my.ns.uri">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="ns:{local-name()}" namespace="http://my.ns.uri">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillStatusCode>
<ns:typecode>1</ns:typecode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
</ns:BillStatusCode>
<ns:EBillProcessStatusCode>
<ns:typecode>2</ns:typecode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
</ns:EBillProcessStatusCode>
<ns:BillCycleCode>
<ns:typecode>1</ns:typecode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
</ns:BillCycleCode>
<ns:BillActivityCode>
<ns:typecode>3</ns:typecode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
</ns:BillActivityCode>
<ns:ToDate>
<ns:BillStatusCode>...</ns:BillStatusCode>
</ns:ToDate>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.