Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
xml-xslt-将所选元素转换为属性_Xml_Xslt_Transform_Stylesheet_Elements - Fatal编程技术网

xml-xslt-将所选元素转换为属性

xml-xslt-将所选元素转换为属性,xml,xslt,transform,stylesheet,elements,Xml,Xslt,Transform,Stylesheet,Elements,我正在尝试将一个XML文档转换为一个新文档,其中只有一个元素将自身转换为属性,并以相同的方式保留文档树的其余部分。。。这是XML文档 <?xml version="1.0" encoding="UTF-8"?> <cities> <city> <cityID>c1</cityID> <cityName>Atlanta</cityName> &

我正在尝试将一个XML文档转换为一个新文档,其中只有一个元素将自身转换为属性,并以相同的方式保留文档树的其余部分。。。这是XML文档

    <?xml version="1.0" encoding="UTF-8"?>
    <cities>
    <city>
        <cityID>c1</cityID>
        <cityName>Atlanta</cityName>
        <cityCountry>USA</cityCountry>
        <cityPop>4000000</cityPop>
        <cityHostYr>1996</cityHostYr>   

    </city>

    <city>
        <cityID>c2</cityID>
        <cityName>Sydney</cityName>
        <cityCountry>Australia</cityCountry>
        <cityPop>4000000</cityPop>
        <cityHostYr>2000</cityHostYr>   
        <cityPreviousHost>c1</cityPreviousHost >   
    </city>

    <city>
        <cityID>c3</cityID>
        <cityName>Athens</cityName>
        <cityCountry>Greece</cityCountry>
        <cityPop>3500000</cityPop>
        <cityHostYr>2004</cityHostYr>   
        <cityPreviousHost>c2</cityPreviousHost >   
    </city>

    </cities>

c1
亚特兰大
美国
4000000
1996
c2
悉尼
澳大利亚
4000000
2000
c1
c3
雅典
希腊
3500000
2004
c2
我试图将“cityID”元素添加到“city”的属性中,并保留其余元素。到目前为止,这里是我的.xsl。不幸的是,它似乎失去了其余的元素:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:template match="/">
        <cities>
            <xsl:apply-templates/>
        </cities>
    </xsl:template>


    <xsl:template match="city">
        <xsl:element name="city" use-attribute-sets="NameAttributes"/>
    </xsl:template>


    <xsl:attribute-set name="NameAttributes">
        <xsl:attribute name="cityID">
            <xsl:value-of select="cityID"/>
        </xsl:attribute>
    </xsl:attribute-set>

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


</xsl:stylesheet>

我会使用

<xsl:template match="city">
    <city cityID="{cityID}">
       <xsl:apply-templates select="node() except cityID"/> <!-- except is XSLT 2.0, use select="node()[not(self::cityID)]" for XSLT 1.0 -->
    </city>
</xsl:template>

或者为其编写一个模板

<xsl:template match="cityID">
  <xsl:attribute name="{name()}" select="."/>
  <!-- XSLT 1.0 <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute> -->
</xsl:template>

所有属性都需要在子节点之前创建,因此使用
可能是该方法工作所必需的


这两个建议都假定存在您拥有的身份转换模板。

与城市元素匹配的模板不会处理此元素的子元素。将其替换为以下内容:

<xsl:template match="city">
    <xsl:element name="city" use-attribute-sets="NameAttributes">
      <xsl:apply-templates select="node()[name()!='cityID']" />
    </xsl:element>
</xsl:template>

就这么简单(完整的XSLT 1.0)转换

<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="city">
    <city cityID="{cityID}">
      <xsl:apply-templates select="@*|node()"/>
    </city>
  </xsl:template>
  <xsl:template match="cityID"/>
</xsl:stylesheet>


这个答案很优雅,但需要XSLT 2。看起来原来的海报使用的是XSLT 1。答案提到了XSLT 1.0替代XSLT/XPath 2.0结构。谢谢Martin,回答得很好-实际上我使用的是1.0,但你也给了我正确的解决方案。。。。10x Bolloyanks Harold,就是他做到的:)很棒,最简单的是,代码没有太多变化