添加新的命名空间非根节点 xslt 1.0
Add new namespace non root node xslt 1.0
我看到了 post XSLT : Add a namespace declaration to the root element
@StuartLC 的答案在根目录中有效。我需要帮助... ¿如何将新的命名空间添加到非根节点?
输入 XML 文档(是的,很恐怖,但它来自客户端)
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<ns3:Response xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<ns3:record>
<registryID>
<registryNumber>232019324</registryNumber>
</registryID>
<ns2:Date>28-08-2019 09:12:32</ns2:Date>
<ns2:registry>
<ns2:type>otp</ns2:type>
<sender>
<ID>260</ID>
</sender>
</ns2:registry>
</ns3:record>
</ns3:Response>
</S:Body>
</soapenv:Envelope>
我想获得:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<record>
<ns1:registryID>
<ns1:registryNumber>232019324</ns1:registryNumber>
</ns1:registryID>
<ns2:Date>28-08-2019 09:12:32</ns2:Date>
<ns2:registry>
<ns2:type>otp</ns2:type>
<ns1:sender>
<ns1:ID>260</ns1:ID>
</ns1:sender>
</ns2:registry>
</record>
</ns3:Response>
</S:Body>
</soapenv:Envelope>
我需要add/remove一些前缀节点。例如节点 <ns3:record>
-> <record>
或节点 <registryID>
-> <ns1:registryID>
或节点 <sender>
-> <ns1:sender>
... 还有更多节点xml输入但我只输入了一些。
我需要在节点响应中包含 ns1,因为当我导入到 SAP PO 时它显示 "ns1 is not declared"。我以为我将前缀 ns1 添加到节点,但我不知道。我在测试 SAP 中手动尝试在节点中包含 ns1 并运行它。在其他转换xslt之后,只有我需要所有xml的节点响应来映射。
这是我使用的 xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name ="mynoderecord">record</xsl:variable>
<xsl:variable name ="mynodeResponse">Response</xsl:variable>
<xsl:variable name ="mynoderegistryNumber">registryNumber</xsl:variable>
<xsl:variable name ="mynodeRegistryID">registryID</xsl:variable>
<xsl:variable name ="mynodesender">sender</xsl:variable>
<xsl:template match="*" >
<xsl:choose>
<xsl:when test="local-name() = $mynodeResponse">
<xsl:element name="ns3:{local-name()}" xmlns:ns3="ws/xml">
<xsl:attribute name="ns1:nsdf" namespace="ttn/xml">sdf</xsl:attribute>
<xsl:for-each select="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynoderegistryNumber" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynodesender" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynodeRegistryID" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynoderecord">
<xsl:element name="{local-name()}" xmlns:ns3="ws/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
搜索时我看到将属性添加到节点 <ns3:Response>
,命名空间 ns1 会自动添加...但我不喜欢。
当然有一个简单的解决方案和更好的代码......
xsl 会让我发疯。
我试过了,但找不到更简单的合适解决方案。
你能告诉我吗?
谢谢
你需要区分"adding a namespace node"和"changing the expanded name of an element"。
对于 Response 元素,您要添加一个命名空间节点,而不更改任何元素或属性的名称。在 XSLT 2.0 中,您可以使用 xsl:namespace
指令来做到这一点。在 XSLT 1.0 中,只能通过相当复杂的解决方法来完成:在新名称空间中创建一个虚拟元素,然后复制其名称空间节点:
<xsl:variable name="dummy">
<ns1:dummy xmlns:ns1="ttn/xml"/>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($dummy)//namespace::*"/>
对于 registryID
元素,您实际上是在更改元素的扩展名,为此您通常需要使用 <xsl:element name="ns1:{local-name()}
/>`
这可能会或可能不会 return 您期望得到的确切结果,具体取决于您的 XSLT 处理器的心血来潮:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="ttn/xml"
xmlns:ns3="ws/xml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns3:Response">
<ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<xsl:apply-templates/>
</ns3:Response>
</xsl:template>
<xsl:template match="ns3:record">
<record xmlns="ttn/xml">
<xsl:apply-templates/>
</record>
</xsl:template>
<xsl:template match="ns1:*">
<xsl:element name="ns1:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,只有第三个模板做任何实质性的事情:它将 ns3:record
移动到不同的命名空间。其他模板是纯粹的装饰品,应该不是必需的。
我看到了 post XSLT : Add a namespace declaration to the root element
@StuartLC 的答案在根目录中有效。我需要帮助... ¿如何将新的命名空间添加到非根节点?
输入 XML 文档(是的,很恐怖,但它来自客户端)
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<ns3:Response xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<ns3:record>
<registryID>
<registryNumber>232019324</registryNumber>
</registryID>
<ns2:Date>28-08-2019 09:12:32</ns2:Date>
<ns2:registry>
<ns2:type>otp</ns2:type>
<sender>
<ID>260</ID>
</sender>
</ns2:registry>
</ns3:record>
</ns3:Response>
</S:Body>
</soapenv:Envelope>
我想获得:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<record>
<ns1:registryID>
<ns1:registryNumber>232019324</ns1:registryNumber>
</ns1:registryID>
<ns2:Date>28-08-2019 09:12:32</ns2:Date>
<ns2:registry>
<ns2:type>otp</ns2:type>
<ns1:sender>
<ns1:ID>260</ns1:ID>
</ns1:sender>
</ns2:registry>
</record>
</ns3:Response>
</S:Body>
</soapenv:Envelope>
我需要add/remove一些前缀节点。例如节点 <ns3:record>
-> <record>
或节点 <registryID>
-> <ns1:registryID>
或节点 <sender>
-> <ns1:sender>
... 还有更多节点xml输入但我只输入了一些。
我需要在节点响应中包含 ns1,因为当我导入到 SAP PO 时它显示 "ns1 is not declared"。我以为我将前缀 ns1 添加到节点,但我不知道。我在测试 SAP 中手动尝试在节点中包含 ns1 并运行它。在其他转换xslt之后,只有我需要所有xml的节点响应来映射。
这是我使用的 xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name ="mynoderecord">record</xsl:variable>
<xsl:variable name ="mynodeResponse">Response</xsl:variable>
<xsl:variable name ="mynoderegistryNumber">registryNumber</xsl:variable>
<xsl:variable name ="mynodeRegistryID">registryID</xsl:variable>
<xsl:variable name ="mynodesender">sender</xsl:variable>
<xsl:template match="*" >
<xsl:choose>
<xsl:when test="local-name() = $mynodeResponse">
<xsl:element name="ns3:{local-name()}" xmlns:ns3="ws/xml">
<xsl:attribute name="ns1:nsdf" namespace="ttn/xml">sdf</xsl:attribute>
<xsl:for-each select="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynoderegistryNumber" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynodesender" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynodeRegistryID" >
<xsl:element name="ns1:{name()}" xmlns:ns1="ttn/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:when test="local-name() = $mynoderecord">
<xsl:element name="{local-name()}" xmlns:ns3="ws/xml">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<!-- procesar atributos de nodo -->
<xsl:for-each select="@*">
<!-- eliminar prefijo de atributo -->
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
搜索时我看到将属性添加到节点 <ns3:Response>
,命名空间 ns1 会自动添加...但我不喜欢。
当然有一个简单的解决方案和更好的代码......
xsl 会让我发疯。
我试过了,但找不到更简单的合适解决方案。
你能告诉我吗?
谢谢
你需要区分"adding a namespace node"和"changing the expanded name of an element"。
对于 Response 元素,您要添加一个命名空间节点,而不更改任何元素或属性的名称。在 XSLT 2.0 中,您可以使用 xsl:namespace
指令来做到这一点。在 XSLT 1.0 中,只能通过相当复杂的解决方法来完成:在新名称空间中创建一个虚拟元素,然后复制其名称空间节点:
<xsl:variable name="dummy">
<ns1:dummy xmlns:ns1="ttn/xml"/>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($dummy)//namespace::*"/>
对于 registryID
元素,您实际上是在更改元素的扩展名,为此您通常需要使用 <xsl:element name="ns1:{local-name()}
/>`
这可能会或可能不会 return 您期望得到的确切结果,具体取决于您的 XSLT 处理器的心血来潮:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="ttn/xml"
xmlns:ns3="ws/xml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns3:Response">
<ns3:Response xmlns:ns1="ttn/xml" xmlns="ttn/xml" xmlns:ns2="rtm/xml" xmlns:ns3="ws/xml">
<xsl:apply-templates/>
</ns3:Response>
</xsl:template>
<xsl:template match="ns3:record">
<record xmlns="ttn/xml">
<xsl:apply-templates/>
</record>
</xsl:template>
<xsl:template match="ns1:*">
<xsl:element name="ns1:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,只有第三个模板做任何实质性的事情:它将 ns3:record
移动到不同的命名空间。其他模板是纯粹的装饰品,应该不是必需的。