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
Xml 在XSLT 2中分组一些没有父元素的模板匹配_Xml_Xslt_Xslt 2.0 - Fatal编程技术网

Xml 在XSLT 2中分组一些没有父元素的模板匹配

Xml 在XSLT 2中分组一些没有父元素的模板匹配,xml,xslt,xslt-2.0,Xml,Xslt,Xslt 2.0,我有一个非常非结构化的XML文档(取自Pandoc转换的docx到docbook格式),我正试图用XSLT清理它。xml的格式如下所示 <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.d

我有一个非常非结构化的XML文档(取自Pandoc转换的docx到docbook格式),我正试图用XSLT清理它。xml的格式如下所示

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
                  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<article>
  <articleinfo>
    <title></title>
  </articleinfo>
<informaltable>
  <tgroup cols="2">
    <colspec align="left" />
    <colspec align="left" />
    <thead>
      <row>
        <entry>
          <emphasis role="strong">How did you assist
          Customer?</emphasis>
        </entry>
        <entry>
          <emphasis>Lorem ipsum dolor sit amet.</emphasis>
        </entry>
      </row>
    </thead>
    <tbody>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
          <emphasis role="strong">What difference did this make for the
          Customer?</emphasis>
        </entry>
        <entry>
          <emphasis>Lorem ipsum dolor sit amet.</emphasis>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>
<para>
  Staff Member: John Smith
</para>
<informaltable>
  <tgroup cols="2">
    <colspec align="left" />
    <colspec align="left" />
    <thead>
      <row>
        <entry>
          <emphasis role="strong">How did you assist
          Customer?</emphasis>
        </entry>
        <entry>
          <emphasis>Lorem ipsum dolor sit amet.</emphasis>
        </entry>
      </row>
    </thead>
    <tbody>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
          <emphasis role="strong">What difference did this make for the
          Customer?</emphasis>
        </entry>
        <entry>
          <emphasis>Lorem ipsum dolor sit amet.</emphasis>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>
<para>
  Staff Member: John Smith
</para>
<informaltable>
  <tgroup cols="2">
    <colspec align="left" />
    <colspec align="left" />
    <thead>
      <row>
        <entry>
          <emphasis role="strong">How did you assist
          Customer?</emphasis>
        </entry>
        <entry>
        </entry>
      </row>
    </thead>
    <tbody>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
          <emphasis role="strong">What difference did this make for the
          Customer?</emphasis>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
      <row>
        <entry>
        </entry>
        <entry>
        </entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>
<para>
  Staff Member: _________________________
</para>
</article>

你是如何协助的
顾客
Lorem ipsum dolor sit amet。
这对整个过程有什么影响
顾客
Lorem ipsum dolor sit amet。
工作人员:约翰·史密斯
你是如何协助的
顾客
Lorem ipsum dolor sit amet。
这对整个过程有什么影响
顾客
Lorem ipsum dolor sit amet。
工作人员:约翰·史密斯
你是如何协助的
顾客
这对整个过程有什么影响
顾客
工作人员:_________________________
我已经用以下XSLT成功地减少了这个问题

<?xml version="1.0"?>

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name="fileDateStamp">
        <xsl:analyze-string select="base-uri(.)" regex="\s*(\d\d\d\d\-\d\d\-\d\d)\s*">
            <xsl:matching-substring>
                <xsl:value-of select="regex-group(1)"/>
            </xsl:matching-substring>
        </xsl:analyze-string>       
    </xsl:variable>

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

    <xsl:template match="informaltable/tgroup/thead/row/entry">
        <xsl:analyze-string select="normalize-space(.)" regex="\s*How(.*)\s*">
            <xsl:matching-substring>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <Assisted>
                    <xsl:value-of select="(.)"/>    
                </Assisted>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

    <xsl:template match="informaltable/tgroup/tbody/row/entry">
        <xsl:analyze-string select="normalize-space(.)" regex="\s*What(.*)\s*">
            <xsl:matching-substring>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <Difference>
                    <xsl:value-of select="(.)"/>
                </Difference>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

    <xsl:template match="para">
        <xsl:analyze-string select="normalize-space(.)" regex="\s*\Staff Member: ([A-Z].*)\s*">
            <xsl:matching-substring>
                <Staff><xsl:value-of select="regex-group(1)"/></Staff>
                <DateCreated><xsl:value-of select="$fileDateStamp"/></DateCreated>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:template>

</xsl:stylesheet> 

但我缺少的是能够在每个“记录”周围添加一个标记。由于
都是
的孩子,我最基本的XSLT知识完全让我失望。我明白了

<?xml version="1.0" encoding="UTF-8"?>
<impactStatements>
   <Assisted>Lorem ipsum dolor sit amet.</Assisted>
   <Difference>Lorem ipsum dolor sit amet.</Difference>
   <Staff>John Smith</Staff>
   <DateCreated>2014-01-01</DateCreated>
   <Assisted>Lorem ipsum dolor sit amet.</Assisted>
   <Difference>Lorem ipsum dolor sit amet.</Difference>
   <Staff>John Smith</Staff>
   <DateCreated>2014-01-01</DateCreated>
</impactStatements>

Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
2014-01-01
Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
2014-01-01
但是我想要

<?xml version="1.0" encoding="UTF-8"?>
<impactStatements>
    <statement>
        <Assisted>Lorem ipsum dolor sit amet.</Assisted>
        <Difference>Lorem ipsum dolor sit amet.</Difference>
        <Staff>John Smith</Staff>
        <DateCreated>2014-01-01</DateCreated>
    </statement>
    <statement>
        <Assisted>Lorem ipsum dolor sit amet.</Assisted>
        <Difference>Lorem ipsum dolor sit amet.</Difference>
        <Staff>John Smith</Staff>
        <DateCreated>2014-01-01</DateCreated>
    </statement>
</impactStatements>

Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
2014-01-01
Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
2014-01-01

这是一项一次性工作,我知道我可以通过其他方式更改XML,但我确信我只是缺乏一些基本知识来更改XSLT,我必须做我想做的事情。我尝试过各种不同的方法,在谷歌上搜索,但都没有用。我所尝试的一切都破坏了生成的XML的格式。

一个有趣且问得很好的问题!将与
/
匹配的模板更改为

<xsl:template match="/article">
    <impactStatements>
    <xsl:for-each select="informaltable">
        <statement>
            <xsl:apply-templates select=". | following-sibling::*[self::para][1]"/>
        </statement>
    </xsl:for-each>
    </impactStatements>
</xsl:template>

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<impactStatements>
   <statement>
      <Assisted>Lorem ipsum dolor sit amet.</Assisted>
      <Difference>Lorem ipsum dolor sit amet.</Difference>
      <Staff>John Smith</Staff>
      <DateCreated/>
   </statement>
   <statement>
      <Assisted>Lorem ipsum dolor sit amet.</Assisted>
      <Difference>Lorem ipsum dolor sit amet.</Difference>
      <Staff>John Smith</Staff>
      <DateCreated/>
   </statement>
   <statement/>
</impactStatements>

Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯

我认为这几乎是正确的。最后有一个空的
语句
,因为输入中有3个
informaltable
元素。您希望如何处理它?

我首先添加一个模板

<xsl:template match="article">
  <xsl:for-each-group select="*" group-starting-with="informaltable">
    <statement>
      <xsl:apply-templates select="current-group()"/>
    </statement>
  </xsl:for-each-group>
</xsl:template>

对于您的示例(并且在添加
以增加可读性之后),我得到了输出

<impactStatements>
   <statement/>
   <statement>
      <Assisted>Lorem ipsum dolor sit amet.</Assisted>
      <Difference>Lorem ipsum dolor sit amet.</Difference>
      <Staff>John Smith</Staff>
      <DateCreated/>
   </statement>
   <statement>
      <Assisted>Lorem ipsum dolor sit amet.</Assisted>
      <Difference>Lorem ipsum dolor sit amet.</Difference>
      <Staff>John Smith</Staff>
      <DateCreated/>
   </statement>
   <statement/>
</impactStatements>

Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯
Lorem ipsum dolor sit amet。
Lorem ipsum dolor sit amet。
约翰·史密斯

我不确定空的
语句
元素是否是由于缺少样本数据造成的,或者您是否希望从处理中排除某些元素,您需要解释输入中的哪些元素应该创建结果
语句

谢谢Martin,对不起,我没有说清楚,我实际上过滤掉了空的
informaltable
para
元素(这两个元素都是链接的,从技术上讲,不仅仅是空的
para
,而是没有名字的元素)。我试着为每个小组做了一次测试,但成功地获得了所有的
辅助
,然后是所有的
差异
,而不是记录在一起!现在我有了一些顺序,我可以在另一个关卡中删除空语句了!感谢Mathias,我曾尝试使用XPath,但完全失败了,这是一个很好的示例。我拥有的实际XML文件在末尾有很多“空的”
informaltable
元素,我想过滤掉这些元素,但我当然可以在第二遍中完成这项工作。