xml - 如何使用 XSLT 从 XML 中删除某些属性

标签 xml regex xslt

我有一个通过网络服务返回给我的 XML 文档。

<Kronos_WFC encoding="ASCII" version="1.0" WFCVersion="6.1" TimeStamp="01/5/2011 8:38AM">
  <Response Status="Success" Timeout="1800" PersonKey="-1" Object="System" Username="1" Action="Logon" PersonNumber="1">
  </Response>
  <Response Status="Success" action="Load">
      <ScheduleGroup ScheduleGroupName="SomeName" AllowsInheritance="false" AllowContract="false" IsEmploymentTerm="false" />
      <ScheduleGroup ScheduleGroupName="GreatName" AllowsInheritance="true" AllowContract="false" IsEmploymentTerm="false" />
      <ScheduleGroup ScheduleGroupName="BestName" AllowsInheritance="true" AllowContract="false" IsEmploymentTerm="false" />
  </Response>
  <Response Status="Success" Object="System" Action="Logoff">
  </Response>
</Kronos_WFC>

问题是我将结果转换为从该产品的 xsd 架构生成的业务对象 (xsd2code)。该产品在属性架构中没有任何内容(对于 Response):

  • 超时
  • 个人 key
  • 对象
  • 用户名

我想做以下事情:

  • 删除上述属性
  • 将所有其他属性转化为元素,包括所有子元素,以及子元素的子元素等。

我如何使用 XLST 执行此操作。使用 Regex 删除不需要的属性会更简单吗?

最佳答案

Would it be simpler to remove the unwanted attributes using Regex?

不,这是一个非常简单的 XSLT 操作:

这个转换:

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "Response/@*[contains('|Timeout|PersonKey|Object|Username|',
                      concat('|',name(),'|')
                      )
            ]"/>
 <xsl:template match="@*">
  <xsl:element name="{name()}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<Kronos_WFC encoding="ASCII" version="1.0"
WFCVersion="6.1" TimeStamp="01/5/2011 8:38AM">
    <Response Status="Success" Timeout="1800" PersonKey="-1"
    Object="System" Username="1" Action="Logon"
    PersonNumber="1"></Response>
    <Response Status="Success" action="Load">
        <ScheduleGroup ScheduleGroupName="SomeName"
        AllowsInheritance="false" AllowContract="false"
        IsEmploymentTerm="false" />
        <ScheduleGroup ScheduleGroupName="GreatName"
        AllowsInheritance="true" AllowContract="false"
        IsEmploymentTerm="false" />
        <ScheduleGroup ScheduleGroupName="BestName"
        AllowsInheritance="true" AllowContract="false"
        IsEmploymentTerm="false" />
    </Response>
    <Response Status="Success" Object="System"
    Action="Logoff"></Response>
</Kronos_WFC>

产生完全想要的、正确的结果:

<Kronos_WFC>
   <encoding>ASCII</encoding>
   <version>1.0</version>
   <WFCVersion>6.1</WFCVersion>
   <TimeStamp>01/5/2011 8:38AM</TimeStamp>
   <Response>
      <Status>Success</Status>
      <Action>Logon</Action>
      <PersonNumber>1</PersonNumber>
   </Response>
   <Response>
      <Status>Success</Status>
      <action>Load</action>
      <ScheduleGroup>
         <ScheduleGroupName>SomeName</ScheduleGroupName>
         <AllowsInheritance>false</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
      <ScheduleGroup>
         <ScheduleGroupName>GreatName</ScheduleGroupName>
         <AllowsInheritance>true</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
      <ScheduleGroup>
         <ScheduleGroupName>BestName</ScheduleGroupName>
         <AllowsInheritance>true</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
   </Response>
   <Response>
      <Status>Success</Status>
      <Action>Logoff</Action>
   </Response>
</Kronos_WFC>

解释:

  1. 身份规则/模板“按原样”复制每个节点。

  2. 覆盖身份规则的模板匹配名称为 TimeoutPersonKeyObjectUsername 的任何属性 有空体并且不复制它们(从输出中“删除”它们)

  3. 匹配任何属性的模板创建一个元素,其名称是匹配属性的名称,其文本节点子节点是匹配属性的值。

记住:使用和覆盖 the identity rule 是最基本和最强大的 XSLT 设计模式。

关于xml - 如何使用 XSLT 从 XML 中删除某些属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6171687/

相关文章:

xml - IE 11/XSLT/XML - 错误

c# - 如何使用 XmlReader 类?

regex - 使用 OR 和 ^ 的 Boost Regex Lookbehind 无效

xslt - 获取所有包含的样式表

c# - 恰好 N 个元素的正则表达式,不多不少

python - 句子中拉长的单词检查

xslt - XSL - 如何比较 2 组节点?

xml - 使用 BaseX 查询 XML 文件

php - 在 PHP 中包含 XML 编码

xml - XPath/XQuery - 选择一个节点同时排除一些元素