XML 命名空间抛弃了我的 XSLT [英] XML Namespace is throwing off my XSLT

查看:25
本文介绍了XML 命名空间抛弃了我的 XSLT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名称空间与此类似的 xml 文档,我只是为了提问而对其进行了简化.

<IDmain>ins</IDmain><Table_1类=实体"><地址>橡树园大道</BillingProviderAddress><城市>伊丽莎白湖</BillingProviderCity><名称>公司</BillingProviderOrgName><InvoiceLine class =entity"><DateService>1234</DateService></InvoiceLine><表_1></MyNameSpace>

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

<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:变量><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:模板></xsl:stylesheet>

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

xmlns=http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace"

两件事,我正在使用 XMLPAD 而当我运行脚本时,它实际上只是那里的名称空间很好.

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

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

有什么想法吗?

解决方案

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

需要添加命名空间前缀;例如:

<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"/>

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

如果您可以使用 XSLT 2.0,您可以使用 xpath-default-namespace 属性为 XPath 查询中引用的元素设置默认命名空间.(XSLT 2.0 在很多小方面更实用,像这样...)

I have an xml document with a name space that looks similar to this, I just simplified it for the sake of asking the question.

<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>

I then created an XSLT here. I understand its ugly, I'm not an XSLT expert but this was one of those "Just solve the problem" moments.

<?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>

Now, The XSLT does exactly what I want it to, the problem is, my test data include this funky namespace at the top of the XML document.

xmlns="http://schemas.microsoft.com/dynamics/2006/02/documents/MyNameSpace"

Two things, I am using XMLPAD and when I run the script it actually does just fine with the name space in there.

Unfortunately, that solution is not ideal because when I attempt to run it in another XSLT tool that I need, (at run time) it does not run correctly.

I know for a fact the namespace is throwing off the XSLT that I am using, because when I remove it from the XML, it runs fine in testing. However, this solution is not plausible because this entire process is in fact automated. So I need a solution to the namespace issue.

Anythoughts?

解决方案

XPath, which is the part of XSLT you're using to match particular elements, is namespace sensitive. When you have an XPath like MyNameSpace/Table_1/Address you're matching elements without any XML namespace; namely any element Address that's a child of any element Table_1 that's a child of any element MyNameSpace that's a child of the current context node.

You need to add namespace prefixes; 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"/>

Unfortunately, XSLT 1.0 does not consider the current default namespace when evaluating XPaths, so you cannot just set the default namespace and be done with it; you really need a namespace prefix.

If you can use XSLT 2.0, you could use the xpath-default-namespace attribute to set the default namespace for elements referenced in XPath queries. (XSLT 2.0 is quite a bit more practical in a lot of small ways, like this...)

这篇关于XML 命名空间抛弃了我的 XSLT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆