具有名称空间的XSL转换

时间:2019-11-13 17:00:05

标签: xml xslt

我有这个xml文件:

<doc xmlns:my="http://example.com" xmlns:my2="test" my:id="AAA">
  <Test>This is the first paragraph.</Test>
  <TEST>This is the second paragraph.</TEST>
  <my2:TEst>This is the second paragraph.</my2:TEst>
</doc> 

我想获得这种格式:

<doc my:id="AAA" xmlns:my="http://example.com" xmlns:my2="test">
  <test>This is the first paragraph.</test>
  <test>This is the second paragraph.</test>
  <my2:test>This is the second paragraph.</my2:test>
</doc>

也就是说,如果一个节点中有一个大写字母,那么我想将所有字母都转换成小写字母(无论在哪里以及在多少个节点中)。

使用此.xls:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="http://example.com" xmlns:my2="test">

  <xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>

  <xsl:template match="@* | node()">
    <new-doc>
      <xsl:apply-templates/>
    </new-doc>
  </xsl:template>

  <xsl:template match="@* | node()">
    <new-doc>
      <xsl:copy-of select="namespace::*"/>
      <xsl:apply-templates/>
    </new-doc>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
  <xsl:element name="{translate(name(.),$vUpper,$vLower)}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
  </xsl:template>

</xsl:stylesheet>

我有这种格式:

<doc my:id="AAA" xmlns:my="http://example.com">
  <test>This is the first paragraph.</test>
  <test>This is the second paragraph.</test>
  <my2:test xmlns:my2="test">This is the second paragraph.</my2:test>
</doc>

我不想在子节点中扩展名称空间。只是别名。我怎样才能达到这个目标?(我对XSL转换很陌生)

谢谢

2 个答案:

答案 0 :(得分:1)

名称空间声明的位置无关紧要。您想要的结果在语义上与您获得的结果相同,因此您无需关心词法差异。

不过,根据您的XSLT处理器的信誉,您也许可以使用以下方法获得想要的结果:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>

<xsl:template match="*">
    <xsl:element name="{translate(name(), $upper, $lower)}" namespace="{namespace-uri()}">
        <xsl:copy-of select="@* | namespace::*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

请注意,这是假设原始名称空间前缀已经是小写字母。

答案 1 :(得分:0)

如果名称空间使用大写形式,确实存在问题:

<doc my:id="AAA" xmlns:my="http://example.com" xmlns:MY2="test">
  <test>This is the first paragraph.</test>
  <test>This is the second paragraph.</test>
  <MY2:test>This is the second paragraph.</MY2:test>
 </doc>

输出为:

<doc my:id="AAA" xmlns:my="http://example.com" xmlns:MY2="test">
  <test>This is the first paragraph.</test>
  <test>This is the second paragraph.</test>
  <my2: xmlns:my2="test" test>This is the second paragraph.</my2:test>
</doc>

我将看到我可以找到其他解决方案。谢谢您的帮助。