I Have a requirement to do a transformation mapping for input xml for which the namespace can change in future.
If I define my input XML with namespace: xmlns:ns1="http://xmlns.sample.com.au/emprec/v1
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:EmpRecord xmlns:ns1="http://xmlns.sample.com.au/emprec/v1">
<ns1:firstname>firstname</ns1:firstname>
<ns1:lastname>lastname</ns1:lastname>
<ns1:address>
<ns1:unit>1</n1:unit>
<ns1:street>st</ns1:street>
<ns1:suburb>suburb</ns1:suburb>
</ns1:address>
</ns1:EmpRecord>
</soap:Body>
</soap:Envelope>
and my XSLT as
<xsl:stylesheet version="1.0"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://xmlns.sample.com.au/emprec/v1"
xmlns:ns2="http://xmlns.sample.com.au/transformtotarget/v1"
xmlns:ora="http://schemas.oracle.com/xpath/extension"
exclude-result-prefixes="xsi xsl xsd wsdl ns1 xp20">
<xsl:template match="/">
<ns2:EMPLOYEES>
<ns2:firstname>
<xsl:value-of select="/ns1:EmpRecord/ns1:firstname"/>
</ns2:firstname>
<ns2:suburb>
<xsl:value-of select="/ns1:EmpRecord/ns1:address/ns1:suburb"/>
</ns2:suburb>
</ns1:EMPLOYEES>
</xsl:template>
</xsl:stylesheet>上面的XSLT运行良好,只要XML的名称空间是http://xmlns.sample.com.au/emprec/v1,如果我的名称空间在将来发生了变化,我如何使用相同的xslt?让我们说:http://xmlns.sample.com.au/emprec/v2
在xpath中映射时,我不想在名称空间前缀,我希望它是动态的。我尝试过使用local-name()函数,它可以工作,但不确定如果我有较大的有效负载会对性能产生什么影响。
<ns2:suburb>
<xsl:value-of select="/*[local-name()='EmpRecord'/*[local-name()='address'/*[local-name()='suburb'"/>
</ns2:suburb>上面的映射工作得很好,但是如果我的xpath很长,这会在性能方面重新建议方法吗?是否有更好的方法来实现这一点?
请帮帮忙。
发布于 2014-01-15 08:40:54
“名称空间可以在未来改变”:公认的智慧是,这不是一个好策略。更改名称空间具有很大的破坏性,这样做的成本几乎总是大于好处。所以人们最终不会去做这件事,即使他们原本打算这样做。(我不知道为什么W3C会在名称空间URI中放置一年时间。很可能当时有人想让它更容易改变。但事实并非如此,相反,这些名称空间永远存在,冻结在时间里。)
如果您想要编写一个处理多个输入词汇表的样式表(这是一个特例),我的建议是为每个使XML规范化以使用单个词汇表的词汇表编写一个预处理阶段。然后,不必在代码中到处处理变体,而是在一个模块中完成这项工作,并且可以编写“真正的”转换,而不必担心这个额外的问题。
你问关于性能的问题,却没有让我们相信它是关键的。代码的可维护性通常更重要。但既然你问:性能取决于你正在使用的产品。如果您使用的是Saxon,那么搜索路径表达式中静态显示的名称比搜索动态提供的字符串的名称要高效得多。
发布于 2014-01-15 00:34:24
性能将取决于您使用的XSLT引擎是如何实现的,但是使用*然后添加谓词以通过本地名称()对其进行限定的方法是XSLT和XPath 1.0提供的最佳方法。
规范的2.0版本允许前缀:*和*:localname的部分通配符。
但是,名称空间名称( URI)实际上不应处于“将来在源处更改”的重大风险。这是您正在处理的文档类型定义的一部分。改变它使它成为一种不同类型的文档。
发布于 2014-01-15 09:24:58
如果我有多个样式表使用一个给定的名称空间,而且某个我无法控制的人强迫我更改名称空间,我将打开一个文本编辑器,并使用该名称空间对我的所有样式表执行一个批处理查找/替换(当然,首先备份它们之后)。这是一次操作,一旦完成,您就可以恢复正常,而不必担心持续的性能影响。
https://stackoverflow.com/questions/21126873
复制相似问题