XML命名空间丢掉了我的XSLT

问题描述:

我有一个名称空间看起来类似于这个的XML文档,我只是为了提出问题而简化它。XML命名空间丢掉了我的XSLT

<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

提供合式输入XML –

+0

[ “重复” 和FAQ](http://stackoverflow.com/questions/1344158/xslt-with-xml-source-that-has-a-default-namespace-set -to-XMLNS)。 –

+2

* XSLT正是我想要的,问题是,我的测试数据* - 这只是让我轻笑。 – LarsH

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

不幸的是,在评估的XPath在XSLT 1.0不考虑当前的默认命名空间,所以你不能只是设置默认的命名空间,并用它做;你真的需要一个名称空间前缀。

如果您可以使用XSLT 2.0,则可以使用xpath-default-namespace属性为XPath查询中引用的元素设置默认名称空间。 (XSLT 2.0是比较实用的相当多了很多小的方面,这样的...)

+0

+1很好的解释 –

你可以使用元素的通用匹配和谓语过滤器上local-name()

例如*[local-name()='MyNameSpace']/*[local-name()='Table_1']/*[local-name()='Address']

警告:这是一个比较通用的搭配,让你可以得到不可预知的结果,如果你有相同名称不同的命名空间限定的内容的文件。