使用XSL提取XML文件的子集并更改一个节点

时间:2017-03-07 12:59:12

标签: xslt

我有这个XML文件

<Person>
   <Name>
      <FirstName>John</FirstName>
      <LastName>Doe</LastName>
   </Name>
   <Address>
      <Street>Grand Street</Street>
      <ZIP>1002</ZIP>
      <City>New York</City>
   </Address>
</Person>

我想要输出:

<Address>
   <Street>Changed Street</Street>
   <ZIP>1002</ZIP>
   <City>New York</City>
</Address>

所以实际上我想提取-Node并更改单个节点

我尝试了下面的xsl,但它只提取了地址节点而没有改变街道节点的值。

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

   <xsl:output omit-xml-declaration="yes"  indent="yes" />
   <xsl:strip-space elements="*"/>

   <xsl:template match="/Person/Address">
      <xsl:copy-of select="." />
   </xsl:template>

   <xsl:template match="/Address/Street">
      <Street>Changed Street</Street>
   </xsl:template>

   <xsl:strip-space elements="*"/>
   <xsl:template match="text()|@*"/>

</xsl:stylesheet>

有没有人知道这种可能性?

1 个答案:

答案 0 :(得分:0)

尝试使用身份模板开始......

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

然后,您只需要担心要为要更改的文档部分创建模板。

因此,要仅选择Address元素,您可以使用此模板执行此操作...

<xsl:template match="Person">
  <xsl:apply-templates select="Address" />
</xsl:template>

请注意使用xsl:apply-templates而不是xsl:copy-of,因为这样可以将模板应用于任何后代节点。

要更改地址节点,请使用这样的模板......

<xsl:template match="Address/Street">
   <Street>Changed Street</Street>
</xsl:template>

请注意州内缺少/。表达式开头的/表示文档节点,因此/Address只会匹配地址(如果它是文档的根元素)。

试试这个XSLT

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

    <xsl:template match="Person">
      <xsl:apply-templates select="Address" />
    </xsl:template>

   <xsl:template match="Address/Street">
      <Street>Changed Street</Street>
   </xsl:template>

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

请注意,您当前的XSLT似乎建议您忽略属性(而不是您的XML示例具有属性),但如果您确实想要忽略它们,请将最后一个模板更改为此...

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