我正在尝试编写 XSLT 代码以将前缀命名空间添加到除少数节点之外的所有节点。
示例 XML:
<BatchPrepareDeliverArchive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="schema">
<BatchInformation>
<RqUId>424000000071256187550913330</RqUId>
<BatchFeedId>CMLTREXT4240</BatchFeedId>
<BatchCount>7</BatchCount>
</BatchInformation>
<BatchDeliverArchive>
<Transactions>
<Transaction>
<TransactionUUID>90022016-01-140000001</TransactionUUID>
<CustomerData>
<GBD_Transactions>
<GBD_Transaction>
<Common_Data>
<Transaction_ID>90022016-01-140000001</Transaction_ID>
</Common_Data>
<Templates>
<Template>
<Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
<Transaction_ID>90022016-01-140000001</Transaction_ID>
</Template>
</Templates>
</GBD_Transaction>
</GBD_Transactions>
</CustomerData>
<DocInfo>
<Name>OPERATION NAME</Name>
</DocInfo>
</Transaction>
</Transactions>
</BatchDeliverArchive>
</BatchPrepareDeliverArchive>
我想向除GBD_Transactions及其子元素以外的所有节点添加 urn 前缀。
我想出了这个 XSLT:
<xsl:stylesheet version="1.0" xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
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="urn:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="urn:{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
所有节点都在这里转换,这不是预期的输出。将不胜感激对此的任何帮助!
如果要忽略GBD_Transactions
元素及其后代,只需添加一个模板以匹配相关节点,并使用标识模板按原样复制它们。
尝试将此模板添加到 XSLT
<xsl:template match="GBD_Transactions|GBD_Transactions//*|GBD_Transactions//@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
请注意,特定元素名称上的匹配比*
上的匹配具有更高的优先级,因此此模板应始终在更通用的模板之前使用。
顺便说一下,您的模板与"*"匹配存在问题。您可能会将其更改为此...
<xsl:template match="*">
<xsl:element name="urn:{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
这是因为<xsl:apply-templates />
与执行<xsl:apply-templates select="node()" />
相同,因此不会选择属性。因此,否则不会调用与@*
匹配的现有模板。
编辑:如果要阻止xsi:schemaLocation
属性成为元素,请添加此模板(您需要在XSLT中声明xsi
命名空间)
<xsl:template match="@xsi:*">
<xsl:copy />
</xsl:template>
或者,也许您不希望将任何属性更改为元素?试试这个 XSLT 吗?
<xsl:stylesheet version="1.0" xmlns:urn="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="urn:{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy />
</xsl:template>
<xsl:template match="GBD_Transactions|GBD_Transactions//*|GBD_Transactions//@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在与"*"匹配的模板中,您应该像这样区分:
<xsl:template match="*">
<xsl:choose>
<xsl:when test="ancestor-or-self::GBD_Transactions">
<xsl:copy>
<xsl:apply-templates"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:element name="urn:{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
输出将如下所示:
<urn:BatchPrepareDeliverArchive xmlns:urn="http://www.w3.org/2001/XMLSchema-instance">
<urn:BatchInformation>
<urn:RqUId>424000000071256187550913330</urn:RqUId>
<urn:BatchFeedId>CMLTREXT4240</urn:BatchFeedId>
<urn:BatchCount>7</urn:BatchCount>
</urn:BatchInformation>
<urn:BatchDeliverArchive>
<urn:Transactions>
<urn:Transaction>
<urn:TransactionUUID>90022016-01-140000001</urn:TransactionUUID>
<urn:CustomerData>
<GBD_Transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<GBD_Transaction>
<Common_Data>
<Transaction_ID>90022016-01-140000001</Transaction_ID>
</Common_Data>
<Templates>
<Template>
<Template_Name>A21_LETTER_FINAL_NOTICE_OF_CANCELLATION_TPA</Template_Name>
<Transaction_ID>90022016-01-140000001</Transaction_ID>
</Template>
</Templates>
</GBD_Transaction>
</GBD_Transactions>
</urn:CustomerData>
<urn:DocInfo>
<urn:Name>OPERATION NAME</urn:Name>
</urn:DocInfo>
</urn:Transaction>
</urn:Transactions>
</urn:BatchDeliverArchive>
</urn:BatchPrepareDeliverArchive>
这就是你想要的吗?