我有一个看起来像这样的XML
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="myns1">
<node1>
<Header>
<MessageID>1</MessageID>
<MessageText>Message1</MessageText>
</Header>
</node1>
</Document>
或者看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="myns2">
<node1>
<Header>
<MessageID>2</MessageID>
<MessageText>Message2</MessageText>
</Header>
</node1>
</Document>
xslt 1.0看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:urn="myns1" exclude-result-prefixes="urn">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/urn:Document">
<Root>
<xsl:apply-templates select="urn:node1/urn:Header" />
</Root>
</xsl:template>
<xsl:template match ="urn:node1/urn:Header">
<Header>
<ID>
<xsl:value-of select="urn:MessageID" />
</ID>
<Text>
<xsl:value-of select="urn:MessageText" />
</Text>
</Header>
</xsl:template>
</xsl:stylesheet>
输出此
<Root>
<Header>
<ID>1</ID>
<Text>Message1</Text>
</Header>
</Root>
我的问题是,我如何支持2个或更多名称空间(例如myns1,myns2和myns3),是否可能,我有一个大的xslt文件,看起来与发布的文件完全相同,编辑整个内容将会采取很长一段时间,是否有更简单的方法来做到这一点。因为输入XML可能会有不同的风格,现在我的xslt只支持一种。
提前致谢
答案 0 :(得分:0)
您可以始终拥有XSLT使用的更多名称空间,XML通常包含多个名称空间。我使用了您的示例,但在XML和XSLT中添加了一个名称空间:
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns="myns1" xmlns:ns2="myns2">
<node1>
<Header>
<ns2:MessageID>1</ns2:MessageID>
<ns2:MessageText>Message2</ns2:MessageText>
</Header>
</node1>
</Document>
在此XML示例中,MessageID和MessageTest现在位于myns2名称空间中,在此XML中以ns2前缀表示。通过将相同的命名空间绑定到我的XSLT中的前缀,我现在可以在XSLT中使用它来识别这两个元素。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:urn="myns1"
xmlns:urn2="myns2" exclude-result-prefixes="urn urn2">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/urn:Document">
<Root>
<xsl:apply-templates select="urn:node1/urn:Header" />
</Root>
</xsl:template>
<xsl:template match ="urn:node1/urn:Header">
<Header>
<ID>
<xsl:value-of select="urn2:MessageID" />
</ID>
<Text>
<xsl:value-of select="urn2:MessageText" />
</Text>
</Header>
</xsl:template>
</xsl:stylesheet>
编辑:
如果要在尝试匹配xpath表达式时忽略命名空间,只需使用元素名称即可使用local-name()函数(XSLT 1.0)
<xsl:value-of select="*[local-name()='MessageID']" />
或者,如果您使用的是XSLT 2.0,则可以使用:
<xsl:value-of select="*:MessageID" />
答案 1 :(得分:0)
当处理几个相似但不相同的输入文件结构变体时(变体名称空间是其中一个可能的例子),我通常的建议是首先将输入规范化为其中一个结构,然后编写转换的其余部分仅适用于该结构。因此,在这种特殊情况下,首先转换文档,使其使用myns1而不是myns2,然后您就可以进行普通的转换。
这样做的主要好处是:(a)它通过分离关注点简化了代码,并且(b)规范化转换具有高度可重用性:您可以随后使用它来处理文档。