Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/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提取信息的XPath查询_Xml_Xpath - Fatal编程技术网

从XML提取信息的XPath查询

从XML提取信息的XPath查询,xml,xpath,Xml,Xpath,这可能是一个棘手的问题,尽管我在XPath方面不是专家。我绞尽脑汁好几天了。 我试图从XML文件中提取某些元素以创建一个表,然后需要通过extractValue从中提取各个值: SELECT [extractValue statements] FROM TABLE( XMLSequence( extract( lv_xml, lv_xpath) ) ) t; 表中的每一行(一列)都应该包含一个XML片段,其中所需元素最多出现一次。它的父节点也应该被提取到表中。问题是,在XML源代码中,所需元素

这可能是一个棘手的问题,尽管我在XPath方面不是专家。我绞尽脑汁好几天了。 我试图从XML文件中提取某些元素以创建一个表,然后需要通过extractValue从中提取各个值:

SELECT [extractValue statements] FROM TABLE( XMLSequence( extract( lv_xml, lv_xpath) ) ) t;
表中的每一行(一列)都应该包含一个XML片段,其中所需元素最多出现一次。它的父节点也应该被提取到表中。问题是,在XML源代码中,所需元素可能也有与我的需求匹配的同级元素。我需要兄弟姐妹在我的结果表中单独列出来

XML看起来与此类似(只是有更多的内容和不同的ID):

也许我能做到,但我显然错了。有什么方法可以实现我想要的吗?

给定输入:

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

<root> 
  <element id="Address"> 
    <assignment name="name1" category="cat1"/>  
    <field id="field1"></field>  
    <field id="field2"></field>  
    <field id="field3"> 
      <assignment name="name5" category="cat2"/>  
      <assignment name="name12" category="cat2"/> 
    </field> 
  </element>  
  <element id="PersonInfo"> 
    <field id="field1"></field>  
    <field id="field2"> 
      <assignment name="name17" category="cat1"/> 
    </field>  
    <field id="field3"></field>  
    <field id="field4"></field> 
  </element> 
</root>

那么您的每个条目是否都有最顶层的父元素:
元素
?谢谢您的评论-是的。永远存在。有时存在,但不总是存在。你能利用XSLT吗?嗯。在不真正了解我所说的100%的情况下,这是取决于开发环境,还是仅仅是转换XML源代码的问题?我可以用我想要的任何方式修改XML,在提取数据后我不需要它。-我使用的是Oracle SQL Developer 3.2,不确定这是否需要任何特定的扩展。它使用XPath。它可以将任意XML文件转换为新的布局,如所需的输出。我不确定你的选择是否有可能,这太棒了。非常感谢你。我一直在玩它,并调整它,以适应我的实际情况,它的工作非常出色-除了一个案例。“赋值”元素的属性“name”的值不必是唯一的。“element”或“field”元素可以有几个“assignment”元素作为具有完全相同名称的子元素(“category”也可以相同,但这是不太可能的)。在这些情况下,XSL转换的输出将在每个部分包含多个“赋值”标记,这意味着我无法处理它。有办法解决这个问题吗?
<element id="Address">
  <assignment name="name1" category="cat1" />
</element>

<element id="Address">
  <field id="field3">
    <assignment name="name5" category="cat2" />
  </field>
</element>

<element id="Address">
  <field id="field3">
    <assignment name="name12" category="cat2" />
  </field>
</element>

<element id="PersonInfo">
  <field id="field2">
    <assignment name="name17" category="cat1" />
  </field>
</element>
//assignment/ancestor-or-self::*
<?xml version="1.0" encoding="UTF-8"?>

<root> 
  <element id="Address"> 
    <assignment name="name1" category="cat1"/>  
    <field id="field1"></field>  
    <field id="field2"></field>  
    <field id="field3"> 
      <assignment name="name5" category="cat2"/>  
      <assignment name="name12" category="cat2"/> 
    </field> 
  </element>  
  <element id="PersonInfo"> 
    <field id="field1"></field>  
    <field id="field2"> 
      <assignment name="name17" category="cat1"/> 
    </field>  
    <field id="field3"></field>  
    <field id="field4"></field> 
  </element> 
</root>
<?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 omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="assignment">
  <xsl:apply-templates select="ancestor::element">
    <xsl:with-param name="assignment-name" select="@name"/>
    <xsl:with-param name="field-id" select="ancestor::field/@id"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="element">
  <xsl:param name="assignment-name"/>
  <xsl:param name="field-id"/>

  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="copy">
      <xsl:with-param name="assignment-name" select="$assignment-name"/>
      <xsl:with-param name="field-id" select="$field-id"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="@*|node()" mode="copy">
  <xsl:param name="assignment-name"/>
  <xsl:param name="field-id"/>

  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="copy">
      <xsl:with-param name="assignment-name" select="$assignment-name"/>
      <xsl:with-param name="field-id" select="$field-id"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="field" mode="copy">
  <xsl:param name="assignment-name"/>
  <xsl:param name="field-id"/>

  <xsl:if test="@id=$field-id">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="copy">
        <xsl:with-param name="assignment-name" select="$assignment-name"/>
        <xsl:with-param name="field-id" select="$field-id"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:if>
</xsl:template>

<xsl:template match="assignment" mode="copy">
  <xsl:param name="assignment-name"/>
  <xsl:param name="field-id"/>

  <xsl:if test="@name=$assignment-name">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="copy">
        <xsl:with-param name="assignment-name" select="$assignment-name"/>
        <xsl:with-param name="field-id" select="$field-id"/>
      </xsl:apply-templates>
    </xsl:copy>  
  </xsl:if>
</xsl:template>

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

<element id="Address">
    <assignment name="name1" category="cat1"/>
</element>
<element id="Address">
    <field id="field3">
        <assignment name="name5" category="cat2"/>
    </field>
</element>
<element id="Address">
    <field id="field3">
        <assignment name="name12" category="cat2"/>
    </field>
</element>
<element id="PersonInfo">
    <field id="field2">
        <assignment name="name17" category="cat1"/>
    </field>
</element>
<?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 omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="assignment">
  <xsl:apply-templates select="ancestor::element">
    <xsl:with-param name="assignment-name" select="@name"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="element">
  <xsl:param name="assignment-name"/>

  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="copy">
      <xsl:with-param name="assignment-name" select="$assignment-name"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="@*|node()" mode="copy">
  <xsl:param name="assignment-name"/>

  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="copy">
      <xsl:with-param name="assignment-name" select="$assignment-name"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="field" mode="copy">
  <xsl:param name="assignment-name"/>

  <xsl:if test="child::assignment[@name=$assignment-name]">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="copy">
        <xsl:with-param name="assignment-name" select="$assignment-name"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:if>
</xsl:template>

<xsl:template match="assignment" mode="copy">
  <xsl:param name="assignment-name"/>

  <xsl:if test="@name=$assignment-name">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="copy">
        <xsl:with-param name="assignment-name" select="$assignment-name"/>
      </xsl:apply-templates>
    </xsl:copy>  
  </xsl:if>
</xsl:template>

</xsl:stylesheet>