XSLT или XPath: как найти узел с определенным тегом и текстом, а затем извлечь его в новый XML-файл? - PullRequest
1 голос
/ 30 января 2012

Мне нужно найти определенный узел в XML-файле, <example>Some text</example>

Затем я хочу извлечь этот узел и его подэлементы из файла XML и записать его в новый файл XML, а затем мне нужно извлечь остальные оставшиеся узлы XML в исходном файле XML, за исключением извлеченного узла, в новый файл XML. после извлеченного узла.

Как я могу сделать это с xslt или xpath?

1 Ответ

2 голосов
/ 30 января 2012

Вот как вывести все узлы минус конкретный узел и его поддерево :

<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="example[. = 'Some text']"/>
</xsl:stylesheet>

когда это преобразование применяется к следующему XML-документу (ничего не было предоставлено!):

<a>
            <example>Some different text</example>
    <b>
        <c>
            <example>Some text</example>
        </c>
            <example>Some other text</example>
    </b>
</a>

желаемый, правильный результат получается :

<a>
    <b>
        <c></c>
    </b>
</a>

Вот как можно извлечь только нужный узел и его поддерево :

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

 <xsl:template match="example[. = 'Some text']">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к тому же XML-документу (см. Выше), результат теперь равен :

<example>Some text</example>

Два разных результирующих документа не могут быть созданы в одном преобразовании XSLT 1.0 .

Вот преобразование XSLT 2.0, которое выводит первый результат и записывает в файл второй результат :

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

 <xsl:variable name="vResult2">
  <xsl:apply-templates mode="result2"/>
 </xsl:variable>

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

 <xsl:template match="example[. = 'Some text']"/>

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

  <xsl:result-document href="file:///c:/temp/delete/result2.xml">
   <xsl:sequence select="$vResult2"/>
  </xsl:result-document>
 </xsl:template>

 <xsl:template mode="result2" match="example[. = 'Some text']">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template mode="result2" match="text()"/>
</xsl:stylesheet>
...