我在这里查了很多答案,我想我差不多了.有一件事是困扰我(并且出于某种原因,我的同伴需要它)如下:
我有以下输入XML:
<?xml version="1.0" encoding="utf-8"?> <MyRoot> <MyRequest CompletionCode="0" CustomerID="9999999999"/> <List TotalList="1"> <Order CustomerID="999999999" OrderNo="0000000001" Status="Shipped"> <BillToAddress ZipCode="22221"/> <ShipToAddress ZipCode="22222"/> <Totals Tax="0.50" SubTotal="10.00" Shipping="4.95"/> </Order> </List> <Errors/> </MyRoot>
我被要求制作这个:
<ns:MyNewRoot xmlns:ns="http://schemas.foo.com/response" xmlns:N1="http://schemas.foo.com/request" xmlns:N2="http://schemas.foo.com/details"> <N1:MyRequest CompletionCode="0" CustomerID="9999999999"/> <ns:List TotalList="1"> <N2:Order CustomerID="999999999" Level="Preferred" Status="Shipped"> <N2:BillToAddress ZipCode="22221"/> <N2:ShipToAddress ZipCode="22222"/> <N2:Totals Tax="0.50" SubTotal="10.00" Shipping="4.95"/> </N2:Order> </ns:List> <ns:Errors/> </ns:MyNewRoot>
注意N2的子代:Order也需要N2:前缀以及其余元素的ns:前缀.
我使用下面的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="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="/MyRoot"> <MyNewRoot xmlns="http://schemas.foo.com/response" xmlns:N1="http://schemas.foo.com/request" xmlns:N2="http://schemas.foo.com/details"> <xsl:apply-templates/> </MyNewRoot> </xsl:template> <xsl:template match="/MyRoot/MyRequest"> <xsl:element name="N1:{name()}" namespace="http://schemas.foo.com/request"> <xsl:copy-of select="namespace::*"/> <xsl:apply-templates select="@* | node()"/> </xsl:element> </xsl:template> <xsl:template match="/MyRoot/List/Order"> <xsl:element name="N2:{name()}" namespace="http://schemas.foo.com/details"> <xsl:copy-of select="namespace::*"/> <xsl:apply-templates select="@* | node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
这个不处理ns(我无法弄清楚).当我使用AltovaXML处理上面的XSL转换时,我最终得到以下结果:
<MyNewRoot xmlns="http://schemas.foo.com/response" xmlns:N1="http://schemas.foo.com/request" xmlns:N2="http://schemas.foo.com/details"> <N1:MyRequest CompletionCode="0" CustomerID="9999999999"/> <List xmlns="" TotalList="1"> <N2:Order CustomerID="999999999" Level="Preferred" Status="Shipped"> <BillToAddress ZipCode="22221"/> <ShipToAddress ZipCode="22222"/> <Totals Tax="0.50" SubTotal="10.00" Shipping="4.95"/> </N2:Order> </List> <Errors/> </MyNewRoot>
请注意,在XSL转换之后,Order的子节点的N2:前缀不存在. Order标头中还有其他xmlns =“”(由于某种原因).我无法弄清楚为其余元素(如错误和列表)添加ns:前缀.
首先,如果父母已经拥有它,为什么我需要为孩子们添加前缀.父命名空间是否指示子节点/属性命名空间?
其次,我想按预期在上面的XML中添加前缀,我该如何使用XSL?
这种转变(仅42行):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://schemas.foo.com/response" xmlns:N1="http://schemas.foo.com/request" xmlns:N2="http://schemas.foo.com/details" > <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="*"> <xsl:element name="ns:{name()}" namespace="http://schemas.foo.com/response"> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> <xsl:template match="@*"> <xsl:copy-of select="."/> </xsl:template> <xsl:template match="/MyRoot"> <xsl:element name="ns:{name()}" namespace="http://schemas.foo.com/response"> <xsl:copy-of select= "document('')/*/namespace::*[name()='N1' or name()='N2']"/> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> <xsl:template match="MyRequest"> <xsl:element name="N1:{name()}" namespace="http://schemas.foo.com/request"> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> <xsl:template match="*[ancestor-or-self::Order]"> <xsl:element name="N2:{name()}" namespace="http://schemas.foo.com/details"> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> </xsl:stylesheet>
当应用于提供的XML文档时:
<MyRoot> <MyRequest CompletionCode="0" CustomerID="9999999999"/> <List TotalList="1"> <Order CustomerID="999999999" OrderNo="0000000001" Status="Shipped"> <BillToAddress ZipCode="22221"/> <ShipToAddress ZipCode="22222"/> <Totals Tax="0.50" SubTotal="10.00" Shipping="4.95"/> </Order> </List> <Errors/> </MyRoot>
产生想要的结果:
<ns:MyRoot xmlns:N1="http://schemas.foo.com/request" xmlns:N2="http://schemas.foo.com/details" xmlns:ns="http://schemas.foo.com/response"> <N1:MyRequest CompletionCode="0" CustomerID="9999999999"/> <ns:List TotalList="1"> <N2:Order CustomerID="999999999" OrderNo="0000000001" Status="Shipped"> <N2:BillToAddress ZipCode="22221"/> <N2:ShipToAddress ZipCode="22222"/> <N2:Totals Tax="0.50" SubTotal="10.00" Shipping="4.95"/> </N2:Order> </ns:List> <ns:Errors/> </ns:MyRoot>
请注意:
>使用< xsl:element>及其名称和命名空间属性.>身份模板如何演变为转换的前两个模板 – 此决定基于以下事实:仅在特殊情况下,元素不得位于ns:名称空间中.>如何为Order元素或其任何后代元素指定N2:名称空间.