Xml XSLT拷贝&;设置属性值

Xml XSLT拷贝&;设置属性值,xml,xslt,Xml,Xslt,下面是我的起始XML: <?xml version="1.0" encoding="UTF-8"?> <root xmlns:something-well-formed"> <child1 attr1="a" attr2="b"> <child1 attr1="c" attr2="b"/> </child1> <child3/> <child1 attr1="d" attr2="b">

下面是我的起始XML:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed"> 
  <child1 attr1="a" attr2="b"> 
     <child1 attr1="c" attr2="b"/>
  </child1>
  <child3/>
  <child1 attr1="d" attr2="b"> 
     <child2 attr1="e" attr2="b"/> 
  </child1>
</root>

我想做的是对上面生成的中间结果运行一个转换,创建一个xml文档,它看起来像下面的示例,在这里我可以指定child1的第n个实例,并相应地设置它的属性:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed"> 
   <child1> 
      <child1/>
   </child1>
   <child3/>
   <child1> 
      <child2 attr1="e" attr2="b"/> 
   </child1>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed"> 
   <child1  attr1="something", attr2="something else"> 
      <child1/>
   </child1>
   <child3/>
   <child1> 
      <child2 attr1="e" attr2="b"/> 
   </child1>
</root>
<xsl:param name="element" />
    <xsl:param name="attributes" />
    <xsl:param name="nodeNumber"/>

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

    <xsl:template match="*[name(.)=$element]">
        <xsl:copy>
            <xsl:apply-templates select="@*" />

            <!-- Splits into separate key/value pairs elements -->
            <xsl:variable name="attributesSeq" select="tokenize($attributes, ';')" />
            <xsl:for-each select="$attributesSeq">
                <xsl:variable name="attributesSeq" select="tokenize(., ',')" />

                <xsl:variable name="key"
                    select="replace($attributesSeq[1], '&quot;', '')" />
                <xsl:variable name="value"
                    select="replace($attributesSeq[2], '&quot;', '')" />

                <xsl:attribute name="{$key}">
                    <xsl:value-of select="$value" />
                </xsl:attribute>
            </xsl:for-each>

            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>


假设您收到此
中的号码:


您可以向模板添加谓词,将变量作为参数传递:

<xsl:template match="*[name(.)=$element][$nodeNumber]">
   ....
</xsl:template>

....
这将根据元素在调用它的上下文中的位置来限制元素

您还有一个用于元素名称的参数。如果您使用:

<xsl:param name="element" select="'child1'" />


它将在
child1
上添加属性。如果将其替换为
'child3'
'child2'
,它将相应地替换它们。(显然,对于示例中的
child3
child2
$nodeNumber
必须为1,因为每个都只有一个。)

Hmmm。如果将“child”限制为根节点的第N个子节点,其名称由
元素给出,则可以完全使用您的方法,但必须替换

<xsl:template match="*[name() = $element]">



这对我很有用(虽然
xsltproc
不接受语法,但我不得不使用Saxon)。但是,如果您希望以子对象的第N个后代实例为目标,该子对象的名称由
元素给出,则该子对象将不起作用。这将更加棘手。我还没有找到答案。

xsltproc拒绝它的原因是因为它不是有效的XSLT 1.0-规范的1.0版禁止在
match
表达式中引用变量,2.0版允许它们。感谢您的提示!1.0和2.0之间还有一个细微的差别::-)我从XSLT1.0.Yep中不存在的
tokenize()
replace()
函数猜到是XSLT2.0。那也是真的<但是,code>xsltproc
并没有对这些问题进行太多的抱怨。
<xsl:template match="*[name() = $element]">
<xsl:template match="*[name() = $element][$nodeNumber]">