Xml 在XSLT 2中分组一些没有父元素的模板匹配
我有一个非常非结构化的XML文档(取自Pandoc转换的docx到docbook格式),我正试图用XSLT清理它。xml的格式如下所示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 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
元素,我想过滤掉这些元素,但我当然可以在第二遍中完成这项工作。