XML命名空间正在抛弃我的XSLT

时间:2011-07-15 15:34:43

标签: xml xslt xml-namespaces

我有一个xml文档,其名称空间与此类似,我只是为了提问而简化它。

<MyNameSpace xmlns="http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace">
<IDmain>ins</IDmain>
    <Table_1 class="entity">
        <Address>Oak Park Drive</BillingProviderAddress>
        <City>Lake Elizabeth</BillingProviderCity>
        <Name>Corporation</BillingProviderOrgName>
        <InvoiceLine class ="entity">
            <DateService>1234</DateService>
        </InvoiceLine>
    <Table_1>
</MyNameSpace>

然后我在这里创建了一个XSLT。我理解它的丑陋,我不是XSLT专家,但这是“只是解决问题”的时刻之一。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">

<xsl:variable name="vPrefix">
<xsl:value-of select="MyNameSpace/Table_1/Address"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="MyNameSpace/Table_1/City"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="MyNameSpace/Table_1/Name"/>
<xsl:text>|</xsl:text>
</xsl:variable>

<xsl:for-each select="MyNameSpace/Table_1/InvoiceLine">
        <xsl:value-of select="$vPrefix"/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="DateService"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

现在,XSLT完全符合我的要求,问题是,我的测试数据在XML文档的顶部包含了这个时髦的命名空间。

的xmlns = “http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace”

有两件事,我正在使用XMLPAD,当我运行脚本时,它实际上就可以使用名称空间。

不幸的是,该解决方案并不理想,因为当我尝试在我需要的另一个XSLT工具中运行它时(在运行时)它无法正常运行。

我知道命名空间正在抛弃我正在使用的XSLT,因为当我从XML中删除它时,它在测试中运行良好。然而,这种解决方案并不合理,因为整个过程实际上是自动化的。所以我需要解决命名空间问题。

Anythoughts?

2 个答案:

答案 0 :(得分:5)

XPath ,它是用于匹配特定元素的XSLT的一部分,是名称空间敏感的。当您拥有像MyNameSpace/Table_1/Address这样的XPath时,您将匹配元素而没有任何XML命名空间;即任何元素Address,它是任何元素Table_1的子元素,它是任何元素MyNameSpace的子元素,它是当前上下文节点的子元素。

您需要添加名称空间前缀; e.g:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:z="http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace">

...

<xsl:value-of select="z:MyNameSpace/z:Table_1/z:Address"/>

不幸的是,在评估XPath时,XSLT 1.0没有考虑当前的默认命名空间,因此不能只设置默认命名空间并完成它;你真的需要一个命名空间前缀。

如果可以使用XSLT 2.0,则可以使用xpath-default-namespace属性为XPath查询中引用的元素设置默认命名空间。 (XSLT 2.0在很多小方面都非常实用,比如......)

答案 1 :(得分:2)

您可以在local-name()

上使用元素的通用匹配和谓词过滤器

e.g。 *[local-name()='MyNameSpace']/*[local-name()='Table_1']/*[local-name()='Address']

警告:这是一种更通用的匹配,因此如果您的文档具有不同的名称空间限定元素并且名称相同,则可能会产生不可预测的结果。