Я проверил много ответов здесь, и я думаю, что я почти там. Одна вещь, которая беспокоит меня (и по какой-то причине это требует мой сверстник):
У меня есть следующий входной 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 (я не мог понять это). Когда я обрабатываю вышеупомянутое XSL-преобразование с AltovaXML, я получаю следующее:
<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>
Обратите внимание, что префикс N2: для потомков Порядка не существует после преобразования XSL. Также дополнительные xmlns = "" в заголовке заказа (по некоторым причинам). Я не мог понять, как поставить префикс ns: для остальных элементов (таких как Errors и List).
Прежде всего, зачем мне ставить префикс для детей, если он уже есть у родителей. Разве родительское пространство имен не определяет дочерние узлы / пространства имен атрибутов?
Во-вторых, я хочу добавить префиксы в приведенный выше XML, как ожидается, как я могу сделать это с XSL?