【问题标题】:How to change a attribute conditionally be checking its sibling's value?如何有条件地更改属性以检查其兄弟的值?
【发布时间】:2012-04-23 22:47:08
【问题描述】:

我只想更改某些特定元素的某些属性值。 例如,是否可以只为以下 XML 中价格为 29.99 的书籍更改 @lang?

<book>
  <title lang="fr">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

【问题讨论】:

    标签: xslt xpath


    【解决方案1】:

    这个简短而简单的转换(根本没有明确的条件)

    <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="book[price=29.99]/title/@lang">
      <xsl:attribute name="lang">ChangedLang</xsl:attribute>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于提供的 XML 时(包装到格式良好的 XML 文档中):

    <t>
        <book>
            <title lang="fr">Harry Potter</title>
            <price>29.99</price>
        </book>
        <book>
            <title lang="eng">Learning XML</title>
            <price>39.95</price>
        </book>
    </t>
    

    产生想要的正确结果

    <t>
       <book>
          <title lang="ChangedLang">Harry Potter</title>
          <price>29.99</price>
       </book>
       <book>
          <title lang="eng">Learning XML</title>
          <price>39.95</price>
       </book>
    </t>
    

    说明:覆盖所需属性的 identity rule

    【讨论】:

      【解决方案2】:

      试试这样的:

      XML 源

      <books>
          <book>
              <title lang="fr">Harry Potter</title>
              <price>29.99</price>
          </book>
          <book>
              <title lang="eng">Learning XML</title>
              <price>39.95</price>
          </book>
      </books>
      

      XSLT 示例

      <?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"/>
          <xsl:template match="/">
              <books>
                  <xsl:for-each select="books/book">
                      <xsl:apply-templates select="."/>
                  </xsl:for-each>
              </books>
          </xsl:template>
          <xsl:template match="book">
                  <book>
                      <title>
                          <xsl:if test="price = '29.99'">
                              <xsl:attribute name="lang">eng</xsl:attribute>
                          </xsl:if>
                      <xsl:value-of select="title"/></title>
                      <price><xsl:value-of select="price"/></price>
                  </book>
          </xsl:template>
      </xsl:stylesheet>
      

      替代模板

      或者你真的想在匹配标题节点时使用以下兄弟轴?如果是这样,这可能会更好:

      <xsl:template match="title">
          <title>
              <xsl:if test="following-sibling::price[1] = '29.99'">
                  <xsl:attribute name="lang">eng</xsl:attribute>
              </xsl:if>
              <xsl:value-of select="."/>
          </title>
      </xsl:template>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 1970-01-01
        • 2015-10-17
        相关资源
        最近更新 更多