【问题标题】:How do I bulk set XML attributes (that area already set)?如何批量设置 XML 属性(该区域已设置)?
【发布时间】:2015-08-07 16:21:13
【问题描述】:

我有一个 xml 文件,root.xml:

    <root>
        <procedure
        topic-file="Procedure1"
        status="Undefined">
        <title> Procedure Number 1 </title>
    </procedure>
    <procedure
        topic-file="Procedure2"
        status="Undefined">
        <title> Procedure Number 2 </title>
    </procedure>
    <procedure
        topic-file="Procedure3"
        status="Undefined">
        <title> Procedure Number 3 </title>
    </procedure>
    <procedure
        topic-file="Procedure4"
        status="Undefined">
        <title> Procedure Number 4 </title>
    </procedure>
</root>

请注意,我正在跟踪 4 个程序。我想一口气改变2个程序的状态。我要更改的内容在此 XML 文件 statusByTitle.xml 中注明

 <?xml version="1.0" encoding="UTF-8"?>
    <statuses>
      <status topic-file="Procedure1">Complete</status>
      <status topic-file="Procedure3">Draft</status>
    </statuses>

我想一次性改变程序 1 和 3 的状态,所以我创建了这个 XSLT 转换:

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

    <!-- set up the key -->
    <xsl:key name="statusByTitle" match="status" use="/topic-file" />

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

    <!-- use the key to set the attribute of the correct procedure -->

      <xsl:template 
         match="item[key('statusByTitle', status,  document('statusByTitle.xml'))]/@status">
      <xsl:attribute name="status">
        <xsl:value-of select="key('statusByTitle', ../status, document('statusByTitle.xml'))" />
    </xsl:attribute>
</xsl:template>

我使用 Saxon-HE 9.5.1.7 在 Oxygen 中运行此转换,输出文件与输入文件相同。我已经盯着这个看了一段时间,找不到错误。我是否以某种方式误解了密钥?

【问题讨论】:

    标签: xml xslt oxygenxml


    【解决方案1】:

    &lt;xsl:key name="statusByTitle" match="status" use="/topic-file" /&gt; 应该是&lt;xsl:key name="statusByTitle" match="status" use="@topic-file" /&gt;。然后你有错误的元素名称item 而不是procedure

      <xsl:template 
             match="procedure[key('statusByTitle', @topic-file,  document('statusByTitle.xml'))]/@status">
          <xsl:attribute name="status" select="key('statusByTitle', ../@topic-file, document('statusByTitle.xml'))" />
    </xsl:template>
    

    我最终得到所有更正

    <xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:param name="status-url" select="'test2015080705.xml'"/>
        <xsl:param name="status-doc" select="doc($status-url)"/>
    
        <!-- set up the key -->
        <xsl:key name="statusByTitle" match="status" use="@topic-file" />
    
        <!-- identity transform -->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <!-- use the key to set the attribute of the correct procedure -->
    
       <xsl:template 
             match="procedure[key('statusByTitle', @topic-file,  $status-doc)]/@status">
          <xsl:attribute name="status" select="key('statusByTitle', ../@topic-file, $status-doc)" />
       </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      相关资源
      最近更新 更多