XSLT命名空间可防止输出中发生更改的标识转换

时间:2012-04-16 17:29:30

标签: xml xslt xslt-2.0

我正在对某些EAD(编码存档描述)XML文档执行XSLT 2.0身份转换。我需要稍微修改输出,但我似乎遇到了命名空间问题。

不要在架构感知处理器中对此进行测试,否则会出错! :)

XSLT:

<?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"
exclude-result-prefixes="#all"
version="2.0">

<xsl:output method="xml" indent="yes" standalone="no"/>

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

<xsl:template match="filedesc">
    <xsl:copy>
        <header>Subjects</header>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>    

Sample-EAD.xml(也可在此处使用pastebin:http://pastebin.com/RFAQaY3w

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ead xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"     xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511" countryencoding="iso3166-1" dateencoding="iso8601" langencoding="iso639-2b">  
<eadid>01234</eadid>
<filedesc>
    <AAA>1</AAA>
    <BBB>2</BBB>
</filedesc>
</eadheader>
<archdesc>
    <bib>
        <CCC>1</CCC>
        <DDD>2</DDD>
    </bib>
</archdesc>
 </ead>

如果我从元素中提取命名空间信息(也可在此处获取:http://pastebin.com/6ygi3xUm),那么带有修改的身份转换就可以了。

采样EAD-2:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ead>

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511" countryencoding="iso3166-1" dateencoding="iso8601" langencoding="iso639-2b">  
<eadid>01234</eadid>
<filedesc>
    <AAA>1</AAA>
    <BBB>2</BBB>
</filedesc>
</eadheader>
<archdesc>
    <bib>
        <CCC>1</CCC>
        <DDD>2</DDD>
    </bib>
</archdesc>

我对命名空间不是很了解所以任何建议都会非常感激。如果我尝试将命名空间添加到XSLT,则转换可以工作,但我在新元素中获得了命名空间属性。非常感谢阅读和阅读你的建议! 干杯!

编辑: 输入(w /名称空间),通过身份转换结果运行 -

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ead xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd">

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511"
          countryencoding="iso3166-1"
          dateencoding="iso8601"
          langencoding="iso639-2b"> 
     <eadid>01234</eadid>
     <filedesc>
           <AAA>1</AAA>
           <BBB>2</BBB>
     </filedesc>
  </eadheader>
  <archdesc>
        <bib>
              <CCC>1</CCC>
              <DDD>2</DDD>
        </bib>
  </archdesc>
</ead>

输入(没有命名空间)通过身份转换结果 -

运行
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ead>

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511"
          countryencoding="iso3166-1"
          dateencoding="iso8601"
          langencoding="iso639-2b"> 
     <eadid>01234</eadid>
     <filedesc>
     <header>Subjects</header>
           <AAA>1</AAA>
           <BBB>2</BBB>
     </filedesc>
  </eadheader>
  <archdesc>
        <bib>
              <CCC>1</CCC>
              <DDD>2</DDD>
        </bib>
  </archdesc>

最后,输入(w /名称空间)通过XSLT(添加了名称空间)结果 -

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0"
xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd"
xmlns:ns2="http://www.w3.org/1999/xlink" 
xmlns="urn:isbn:1-931666-22-9"  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<xsl:output method="xml" indent="yes" standalone="no"/>

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

<xsl:template match="filedesc">
    <xsl:copy>
        <header>Subjects</header>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>    

</xsl:stylesheet>

结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ead xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd">

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511"
          countryencoding="iso3166-1"
          dateencoding="iso8601"
          langencoding="iso639-2b"> 
     <eadid>01234</eadid>
     <filedesc>
           <AAA>1</AAA>
           <BBB>2</BBB>
     </filedesc>
  </eadheader>
  <archdesc>
        <bib>
              <CCC>1</CCC>
              <DDD>2</DDD>
        </bib>
  </archdesc>
</ead>
编辑#2:编辑#2: 道歉,因为我认为我没有表达我想要的输出。我想避免修改元素中的其他属性,因为在身份转换后会进行额外的处理,并且我希望尽可能使XML保持接近当前状态(编辑除外) )。再次感谢您的耐心等待救命!这是一个例子:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ead xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd" xmlns:ns2="http://www.w3.org/1999/xlink" xmlns="urn:isbn:1-931666-22-9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<eadheader findaidstatus="Ready_for_online" repositoryencoding="iso15511" countryencoding="iso3166-1" dateencoding="iso8601" langencoding="iso639-2b">  
    <eadid>01234</eadid>
    <filedesc>
        <header>List Name</header>
        <AAA>1</AAA>
        <BBB>2</BBB>
    </filedesc>
</eadheader>
<archdesc>
    <bib>
        <CCC>1</CCC>
        <DDD>2</DDD>
    </bib>
</archdesc>
</ead>

1 个答案:

答案 0 :(得分:0)

这是一个很长的问题,有点难以理解,但我认为这就是你想要的。这笔交易是您要匹配的元素位于源xml文档中的命名空间中,因此您也必须匹配命名空间。因此我在xslt中为它指定了一个前缀:xmlns:input="urn:isbn:1-931666-22-9"然后我使用它来匹配filedesc元素:<xsl:template match="input:filedesc">。我还使相同的命名空间成为xsl的默认命名空间,因此您的元素将位于该命名空间中。

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:input="urn:isbn:1-931666-22-9"
    xmlns="urn:isbn:1-931666-22-9"
    exclude-result-prefixes="input"
    version="2.0">

  <xsl:output method="xml" indent="yes" standalone="no"/>

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

  <xsl:template match="input:filedesc">
    <xsl:copy>
      <header>Subjects</header>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>  
</xsl:stylesheet>