XSLT:是否可以盲目传递大多数元素而转换特定元素?

时间:2018-09-19 20:16:41

标签: xml xslt

给出一个包含元素a,b,c和d的xml文件,是否可以编写一个XSLT,该XSLT仅更改元素“ c”并盲目传递所有其他元素?

例如:

<?xml version="1.0" encoding="UTF-8"?>
<Person>
    <a>pass me blindly</a>
    <b>pass me blindly</b>
    <c>I need XSLT to convert me</c>
    <d>pass me blindly</d>
</Person>

是否可以使用XSLT进行“ c”的转换,而所有其他元素都按原样在源中传递?

我最终会得到:

<?xml version="1.0" encoding="UTF-8"?>
<Person>
    <a>pass me blindly</a>
    <b>pass me blindly</b>
    <c>I've been CONVERTED!</c>
    <d>pass me blindly</d>
</Person>

是的,我对XSLT的知识水平是有限的。

3 个答案:

答案 0 :(得分:2)

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<?xml-stylesheet type="text/xml" href=".\XSLTFile1.xslt"?>
 <Person >
  <a>pass me blindly</a>
  <b>pass me blindly</b>
  <c>I need XSLT to convert me</c>
  <d>pass me blindly</d>
</Person>

以下XSL转换模板将为您提供所需的结果

<?xml version="1.0" encoding="utf-8"?>
<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" omit-xml-declaration="yes" />
  <xsl:template match="xsl:stylesheet" />
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="c">
    <c>I've been CONVERTED!</c>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

您有两种实现所需目标的可能性:

  • 白名单方法和
  • 黑名单方法

第一个节点复制除白名单以外的所有节点,这些节点的处理方式不同:

<?xml version="1.0" encoding="UTF-8"?>
<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" omit-xml-declaration="yes" />

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

  <xsl:template match="c">
    <xsl:value-of select="concat('The node ',name(),' is being processed.')" />
  </xsl:template>  

</xsl:stylesheet>

第二个节点仅复制不应该进一步处理的列入黑名单的节点:

<?xml version="1.0" encoding="UTF-8"?>
<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" omit-xml-declaration="yes" />

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

  <xsl:template match="a | b | d" priority="1">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>   

  <xsl:template match="*[parent::Person]" priority="0">
    <xsl:value-of select="concat('The node ',name(),' is being processed.')" />
  </xsl:template>   

</xsl:stylesheet>

答案 2 :(得分:0)

正如您提到的Altova一样,您也许还可以使用XSLT 3(如果您拥有Altova的当前版本),而在XSLT 3中,您可以将xsl:mode on-no-match与不同的值on-no-match? = "deep-copy" | "shallow-copy" | "deep-skip" | "shallow-skip" | "text-only-copy" | "fail"一起使用,请参见{ {3}}和https://www.w3.org/TR/xslt-30/#built-in-rule

的声明
<xsl:mode on-no-match="shallow-copy"/>

将身份转换建立为未命名模式的内置规则。然后,您只需要为要转换的元素添加模板。