xml - 使用 xslt 更改属性值

标签 xml xslt xml-attribute spring-bean

还有许多其他问题涉及该领域,但我无法使那里的解决方案发挥作用

我有一个转换,可以将包含多个 bean 的 Spring bean 文件拆分为一组文件,每个文件包含一个 bean

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/beans/bean" xml:space="preserve"> 
            <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," ", "_")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <xsl:copy-of select="."/>
</beans>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>

这工作正常,生成的文件如下所示:

<!DOCTYPE beans
  PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean class="com.class.mine.Policy" name="bean1">
        <property name="name">

为了使该文件看起来与最初创建的仅包含一个 bean 的文件相同(因为该文件将被 checkin 源代码管理,我只想要真正的差异),我想更改 name="beanN" 属性到每个文件中的 name="bean0"。请注意,通常 bean 标记可以包含其他属性以及 classname 属性。

我根据这里的其他答案尝试过的任何方法都不起作用。大多数情况下,我收到有关“无法创建父级是文档节点的属性节点”和“在创建包含元素的子级后无法创建属性节点”的错误。

所以我遗漏了一些明显的东西。我需要添加什么才能进行此额外更改?

更新:问题似乎部分与 xml:space="preserve"有关。这可能会导致创建文本节点。删除后,我不会经常收到错误,但我仍然无法正确进行转换

(输出有

<beans><bean>

如何在这些标签之间获取换行符?我可以使用 indent="yes"来格式化输出,但我真的想保留输入格式,因为它是原来的,只在我必须的地方进行更改)

更新:我的众多尝试之一。这个可以运行,但基本上是一个身份转换。 result-doc 已被注释掉,以便暂时更轻松地进行调试。我真的不明白 xsl:attribute 是如何工作的,所以一个合适的解释可能会有所帮助。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="beans/bean"> 
<!--             <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," /", "_+")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd"
            omit-xml-declaration="no"> -->
<beans>
<xsl:apply-templates select="bean"/>
<xsl:copy-of select="." /> 
</beans>
<!-- </xsl:result-document> -->
</xsl:template>
 <xsl:template match="bean/@*">
      <xsl:copy>
          <xsl:attribute name="name">myvalue</xsl:attribute>
           <xsl:copy-of select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

最佳答案

如果您想要特定的缩进,那么您必须自己插入相关的换行符和空格:

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

  <xsl:template match="/">
    <xsl:apply-templates select="beans/bean" />
  </xsl:template>

  <xsl:template match="bean"> 
    <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," /", "_+")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd"
            omit-xml-declaration="no">
      <xsl:text>&#10;</xsl:text><!-- newline after the DOCTYPE -->
      <beans>
        <xsl:text>&#10;    </xsl:text><!-- newline and four spaces -->
        <bean>
          <xsl:copy-of select="@*" />
          <xsl:attribute name="name">bean0</xsl:attribute>
          <xsl:copy-of select="node()" />
        </bean>
        <xsl:text>&#10;</xsl:text><!-- newline between </bean> and </beans> -->
      </beans>
    </xsl:result-document>
  </xsl:template>
</xsl:stylesheet>

对于重命名:

        <bean>
          <xsl:copy-of select="@*" />
          <xsl:attribute name="name">bean0</xsl:attribute>
          <xsl:copy-of select="node()" />
        </bean>

首先,我复制原始 bean 标记中的所有属性(可能包括 name),然后创建一个(另一个)name 属性,该属性会覆盖复制的节点,最后复制原来的 bean 元素的所有子节点(包括元素、注释文本节点,所以会保留原来的缩进)。

关于xml - 使用 xslt 更改属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20131498/

相关文章:

xml 元素作为对象 HTMLCollection 返回

xml - 如何测试 XSLT 中空格分隔值的所有排列?

java - Xalan with Java 6 会跳过注释吗?

c# - 如何使用反序列化使用 C# 类读取 xml 属性

sql-server-2008 - 从 SQL Server 2008 表中的 XML 字段中提取属性

vbscript - 检索 VBS 中 XML 属性的值

java - 如何使用 dom 解析器在 xml 中写入特殊字符( &、<、> 等)

JQuery xml/xhtml 处理

xml - OpenCV XML分类器

xml - XSLT - 如果属性值字符长度大于 10,则为 bool 值 true