XSLT-预定义NameSpace

时间:2015-04-29 07:19:52

标签: parsing xslt namespaces

您好我有一个XML,每次交付时都有一个不同的唯一名为Namespace,我无法通过标准流程预先确定。

<ABC xmlns:this="urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331" version="1.1">
<Extensions>
  <Identification>urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331</Identification>
  <Extension>
    <SrcPackage>
        <this:ABDList>
          <TaggedValue>111</TaggedValue>
        </this:ABDList>
        <this:SubBegin>0</this:SubBegin>
    </SrcPackage>
    <MatPackage>
        <this:ABDList>
          <TaggedValue>222</TaggedValue>
        </this:ABDList>
        <this:SubBegin>1</this:SubBegin>
    </MatPackage>
    <!-- Stuff -->
  </Extention>
</Extentions>
</ABC>

提供的Next XML可能是

<ABC xmlns:this="urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331" version="1.1">
<Extensions>
  <Identification>urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331</Identification>
  <Extension>
    <SrcPackage>
        <this:ABDList>
          <TaggedValue>333</TaggedValue>
        </this:ABDList>
        <this:SubBegin>0</this:SubBegin>
    </SrcPackage>
    <MatPackage>
        <this:ABDList>
          <TaggedValue>444</TaggedValue>
        </this:ABDList>
        <this:SubBegin>1</this:SubBegin>
    </MatPackage>
    <!-- Stuff -->
  </Extention>
</Extentions>
</ABC>

我当前的XSL样式表适用于预定义命名空间的第一个XML 但我希望找到一种方法可以在以后重新定义它。在这个过程中。我添加了一个变量来从Identification元素中提取相关的uuid,但我不确定如何集成它。使用以下样式表处理任何其他XML会导致错误结果。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:this="urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*"/>

<xsl:variable name="SelOpGroup" select="/ABC/Extensions/Identification"/>

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

<xsl:template match="/ABC/Extensions/SrcPackage>
  <xsl:copy>
            <this:ABDList>
                <xsl:copy-of select ="this:ABDList/*"/>
                <TaggedA>888</TaggedA>
            </this:ABDList>
            <this:SubBegin><xsl:value-of select="somethingelse"/> </this:SubBegin>
  </xsl:copy>
</xsl:template>

<xsl:template match="/ABC/Extensions/MatPackage>
  <xsl:copy>
            <this:ABDList>
                <xsl:copy-of select ="this:ABDList/*"/>
                <TaggedB>999</TaggedB>
            </this:ABDList >
            <this:SubBegin><xsl:value-of select="somethingelse"/> </this:SubBegin>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

预期结果

<ABC xmlns:this="urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331" version="1.1">
<Extensions>
  <Identification>urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331</Identification>
  <Extension>
    <SrcPackage>
        <this:ABDList>
          <TaggedValue>333</TaggedValue>
          <TaggedA>888</TaggedA>
        </this:ABDList>
        <this:SubBegin>a value</this:SubBegin>
    </SrcPackage>
    <MatPackage>
        <this:ABDList>
          <TaggedValue>444</TaggedValue>
          <TaggedB>999</TaggedA>
        </this:ABDList>
        <this:SubBegin>a value</this:SubBegin>
    </MatPackage>
    <!-- Stuff -->
  </Extention>
</Extentions>
</ABC>

非常感谢, 阿德里安

3 个答案:

答案 0 :(得分:1)

这是奇怪的输入(他们吸烟的是什么?)。但由于命名空间仅用于一个元素ABDList,我的方法是在XSLT 2.0中使用*:ABDList或在XSLT 1.0中使用*[local-name()='ABDList']来选择ABDList元素。

答案 1 :(得分:1)

此转化

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

  <xsl:variable name="SelOpGroup" select="/ABC/Extensions/Identification"/>

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

  <xsl:template match="Extension/SrcPackage">
    <xsl:copy>
            <xsl:element name="{'this:ABDList'}" namespace="{$SelOpGroup}">
                <xsl:copy-of select="/*/namespace::*[name()='this']"/>
                <xsl:copy-of select ="*[name() = 'this:ABDList']/*"/>
                <TaggedA>888</TaggedA>
            </xsl:element>
            <xsl:element name="{'this:SubBegin'}" namespace="{$SelOpGroup}">
                <xsl:copy-of select="/*/namespace::*[name()='this']"/>
                <xsl:value-of select="'somethingelse'"/>
            </xsl:element>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Extension/MatPackage">
    <xsl:copy>
            <xsl:element name="{'this:ABDList'}" namespace="{$SelOpGroup}">
                <xsl:copy-of select="/*/namespace::*[name()='this']"/>
                <xsl:copy-of select ="*[name() = 'this:ABDList']/*"/>
                <TaggedB>999</TaggedB>
            </xsl:element>
            <xsl:element name="{'this:SubBegin'}" namespace="{$SelOpGroup}">
                <xsl:copy-of select="/*/namespace::*[name()='this']"/>
                <xsl:value-of select="'somethingelse'"/>
            </xsl:element>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

应用于第一个提供的XML文档

<ABC xmlns:this="urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331" version="1.1">
    <Extensions>
        <Identification>urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331</Identification>
        <Extension>
            <SrcPackage>
                <this:ABDList>
                    <TaggedValue>111</TaggedValue>
                </this:ABDList>
                <this:SubBegin>0</this:SubBegin>
            </SrcPackage>
            <MatPackage>
                <this:ABDList>
                    <TaggedValue>222</TaggedValue>
                </this:ABDList>
                <this:SubBegin>1</this:SubBegin>
            </MatPackage>
            <!-- Stuff -->
        </Extension>
    </Extensions>
</ABC>

生成想要的正确结果

<ABC xmlns:this="urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331" version="1.1">
   <Extensions>
      <Identification>urn:uuid:9b1f15a9-69de-11d2-b6bc-fcab70ff7331</Identification>
      <Extension>
         <SrcPackage>
            <this:ABDList>
               <TaggedValue>111</TaggedValue>
               <TaggedA>888</TaggedA>
            </this:ABDList>
            <this:SubBegin>somethingelse</this:SubBegin>
         </SrcPackage>
         <MatPackage>
            <this:ABDList>
               <TaggedValue>222</TaggedValue>
               <TaggedB>999</TaggedB>
            </this:ABDList>
            <this:SubBegin>somethingelse</this:SubBegin>
         </MatPackage><!-- Stuff -->
      </Extension>
   </Extensions>
</ABC>

对第二个提供的XML文档应用相同的转换

<ABC xmlns:this="urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331" version="1.1">
<Extensions>
  <Identification>urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331</Identification>
  <Extension>
    <SrcPackage>
        <this:ABDList>
          <TaggedValue>333</TaggedValue>
        </this:ABDList>
        <this:SubBegin>0</this:SubBegin>
    </SrcPackage>
    <MatPackage>
        <this:ABDList>
          <TaggedValue>444</TaggedValue>
        </this:ABDList>
        <this:SubBegin>1</this:SubBegin>
    </MatPackage>
    <!-- Stuff -->
  </Extension>
</Extensions>
</ABC>

再次生成想要的正确结果

<ABC xmlns:this="urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331" version="1.1">
   <Extensions>
      <Identification>urn:uuid:9b1FFae4-69de-11d2-b6bc-fcab70ff7331</Identification>
      <Extension>
         <SrcPackage>
            <this:ABDList>
               <TaggedValue>333</TaggedValue>
               <TaggedA>888</TaggedA>
            </this:ABDList>
            <this:SubBegin>somethingelse</this:SubBegin>
         </SrcPackage>
         <MatPackage>
            <this:ABDList>
               <TaggedValue>444</TaggedValue>
               <TaggedB>999</TaggedB>
            </this:ABDList>
            <this:SubBegin>somethingelse</this:SubBegin>
         </MatPackage><!-- Stuff -->
      </Extension>
   </Extensions>
</ABC>

答案 2 :(得分:0)

  

我有一个XML,每次交付时都有一个不同的唯一命名   命名空间

在你面前的人显然不明白拥有命名空间的目的。

也许这对你不幸的情况有用:

XSLT 1.0

<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:strip-space elements="*"/>

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

<xsl:template match="SrcPackage/*/TaggedValue">
    <xsl:copy-of select="."/>
    <TaggedA>888</TaggedA>
</xsl:template>

<xsl:template match="MatPackage/*/TaggedValue">
    <xsl:copy-of select="."/>
    <TaggedB>999</TaggedB>
</xsl:template>

</xsl:stylesheet>