Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.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
Xslt 用于排除某些子节点的XPath表达式_Xslt_Xpath - Fatal编程技术网

Xslt 用于排除某些子节点的XPath表达式

Xslt 用于排除某些子节点的XPath表达式,xslt,xpath,Xslt,Xpath,我有一个源XML树: <?xml version="1.0" encoding="UTF-8"?> <root> <foo> <bar> <baz> <item> <methods> <item> <id>1</id> </item>

我有一个源XML树:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo>
    <bar>
      <baz>
        <item>
          <methods>
            <item>
              <id>1</id>
            </item>
          </methods>
          <id>1</id>
        </item>
        <item>
          <methods>
            <item>
              <id>19</id>
            </item>
          </methods>
          <id>2</id>
        </item>
      </baz>
    </bar>
  </foo>
  <bar_method>
    <root>
      <bla id="1">
        <methods>
          <method id="1">
            <calc md="ck" />
            <tm m="14" />
            <price_list>
              <price mse="0">
                <ins re="0" />
              </price>
            </price_list>
          </method>
          <method id="2">
            <calc md="qck" />
            <tm m="4" />
            <price_list>
              <price mse="1">
                <ins re="0" />
              </price>
            </price_list>
          </method>
        </methods>
      </bla>
      <bla id="2">
        <methods>
          <method id="19">
            <calc md="dd" />
            <tm m="3" />
            <price_list>
              <price mse="01">
                <ins re="0" />
              </price>
            </price_list>
          </method>
        </methods>
      </bla>
    </root>
  </bar_method>
</root>

看起来您需要所有
bla
元素,并且只需要每个元素中的第一个
methods/method
元素。是这样吗

您不能在单个XPath表达式中实现这一点,因为您只能限制要选择的元素—您也不能过滤掉它们的一些后代。但是使用模板是可能的

此样式表创建变量
$meth
,并使用
copy of
将其输出

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

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:variable name="meth">
      <xsl:apply-templates select="root/bar_method/root/bla"/>
    </xsl:variable>
    <xsl:copy-of select="$meth"/>
  </xsl:template>

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

  <xsl:template match="methods">
    <xsl:copy>
      <xsl:apply-templates select="method[1]"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输出

<bla id="1">
   <methods>
      <method id="1">
         <calc md="ck"/>
         <tm m="14"/>
         <price_list>
            <price mse="0">
               <ins re="0"/>
            </price>
         </price_list>
      </method>
   </methods>
</bla>
<bla id="2">
   <methods>
      <method id="19">
         <calc md="dd"/>
         <tm m="3"/>
         <price_list>
            <price mse="01">
               <ins re="0"/>
            </price>
         </price_list>
      </method>
   </methods>
</bla>

XPath只能选择节点,不能更改节点。也就是说,所选节点的子节点和子节点将始终与源文档中的子节点和子节点完全相同


如果要创建与输入树不同的树,则需要XSLT或XQuery。

为什么需要将片段放在变量中。您希望从XSL中获得什么输出?看起来你需要模板。我只是想知道这是否可能。看起来你需要所有
bla
元素,并且每个元素中只有第一个
methods/method
元素。是这样吗?您不能在单个XPath表达式中实现这一点,因为您只能限制要选择的元素—您也不能过滤掉它们的一些后代。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:variable name="meth">
      <xsl:apply-templates select="root/bar_method/root/bla"/>
    </xsl:variable>
    <xsl:copy-of select="$meth"/>
  </xsl:template>

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

  <xsl:template match="methods">
    <xsl:copy>
      <xsl:apply-templates select="method[1]"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
<bla id="1">
   <methods>
      <method id="1">
         <calc md="ck"/>
         <tm m="14"/>
         <price_list>
            <price mse="0">
               <ins re="0"/>
            </price>
         </price_list>
      </method>
   </methods>
</bla>
<bla id="2">
   <methods>
      <method id="19">
         <calc md="dd"/>
         <tm m="3"/>
         <price_list>
            <price mse="01">
               <ins re="0"/>
            </price>
         </price_list>
      </method>
   </methods>
</bla>