Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
787 views
in Technique[技术] by (71.8m points)

xslt - running xsl transform mutltiple time results in xml:lang attribute replaced with lang attribute

I am running an XSL transform to change some DITA XML. The first part of the code finds a matching number format - e.g. 574-1234 - and places the number in a keyref. This works as expected.

However, I want to add an xml:lang attribute to matching instances too. This all works the first time I run the transform. But if I run the transform a second time, the xml:lang attribute changes to lang only.

Why!?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en-US"
  xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/"
  exclude-result-prefixes="xs ditaarch xsl" version="2.0">
  <xsl:output method="xml" omit-xml-declaration="no" version="1.0" indent="yes"/>

  <xsl:template match="text()">
    <xsl:analyze-string select="."
      regex="(574-dddd)">
      <xsl:matching-substring>
        <xsl:choose>
          <xsl:when test="matches(., '574-dddd')">
            <ph>
              <xsl:attribute name="keyref">
                <xsl:value-of select="."/>
              </xsl:attribute>
              <xsl:attribute name="xml:lang">
                <xsl:text>en-us</xsl:text>
              </xsl:attribute>
            </ph>
          </xsl:when>
          <!-- End product family xsl -->
        </xsl:choose>

      </xsl:matching-substring>

      <!-- Let everything non matching fall thruough -->
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>

    </xsl:analyze-string>

  </xsl:template>

</xsl:stylesheet>

Original XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="concept_elb_jny_l4b">
    <title xml:lang="en-us">test</title>
    <conbody>
        <p>574-1234</p>
    </conbody>
</concept>

First time output, xml:lang added correctly to the keyref. xml:lang changes to lang in the title element:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="concept_elb_jny_l4b">
   <title lang="en-us">test</title>
   <conbody>
      <p>
         <ph keyref="574-1234" xml:lang="en-us"/>
      </p>
   </conbody>
</concept>

Second time running the transform, only lang attributes remain:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="concept_elb_jny_l4b">
   <title lang="en-us">test</title>
   <conbody>
      <p>
         <ph keyref="574-1234" lang="en-us"/>
      </p>
   </conbody>
</concept>

Thanks for any help.

question from:https://stackoverflow.com/questions/65929155/running-xsl-transform-mutltiple-time-results-in-xmllang-attribute-replaced-with

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Looks like transformation copies local-name of your attributes.

Please check if you use template similar to this:

<xsl:template match="@*" priority="-1">
    <xsl:attribute name="{local-name()}">
        <xsl:value-of select="."/>
     </xsl:attribute>
</xsl:template>

If yes, then use xsl:copy instead of xsl:attribute. Following template should fix it:

<xsl:template match="@*" priority="-1">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...