2016-08-17 60 views
0

我正在重构批处理XML文档,并且此过程涉及将xml重新构建为新的修订后的DTD架构。由于使用了新的DTD,最初使用的许多元素都被重新使用,重新嵌套在其他元素中,或者被完全删除。 以下示例在针对DTD进行验证时是无效的xml文档。为了加速重构XML的过程,我想可能是XQuery脚本或XSLT转换可能会有所帮助。不过,我对这两者都没有任何经验,而且对XML还是比较陌生。有人能够向我解释在重构这些文档时,XQuery,XSLT或Xpath是最重要的哪种语言。重构使用XSLT或XQuery脚本重新嵌套元素

无效XML:

<PartsDoc foo=”” baa=”” bar=”” revno=”” docno=”” > 
    <PartsDocInfo> 
     <repairlvl level=”shop” /> 
     <title id=”123”> Foo Electrical Control Box </title> 
    </PartsDocInfo> 

    <Parts.Category> 

    <figure id=”123” > 
     <title id=”123”> Control Box Panels </title> 

    <subfig id=”123”> 
      <graphic img=”foo.jpg” /> 
     </subfig> 
    <!- - everything above is valid, the below portion is not - -> 



<parts.item> 
      <callout id=”123” config=”123” label=”1” /> 
      <mrs service=”shop” sc=”” mc=”” rec=”” /> 
      <nsn niin=”00-123-4567”> 4444-00-123-5467</nsn> 
      <cageno>12345</cageno> 
      <partno>12345</partno> 
      <name/> 
      <desc id=”123” > Bolt 1/2inch </desc> 
      <qty>4</qty> 
<parts.item> 
    </parts.category> 

所需的输出:

<PartsDoc foo=”” baa=”” bar=”” revno=”” docno=”” > 

     <PartsDocInfo> 
     <repairlvl level=”shop” /> 
     <title id=”123”> Foo Electrical Control Box </title> 
    </PartsDocInfo> 
<Parts.Category> 
    <figure id=”123” > 
     <title id=”123”> Control Box Panels </title> 
<subfig id=”123”> 
      <graphic img=”foo.jpg” /> 
</subfig> 
    <parts.item> 
     <callout id=”123” config=”123” label=”1” /> 
<qty>4</qty> 
<mrs service=”shop” sc=”” mc=”” rec=”” /> 
<nsn> 
     <fsc>4444</fsc> 
     <niin>00-12-5467 
</nsn> 
     <partno>12345</partno> 
     <cageno>12345</cageno> 
     <name/> 
     <desc id=”123” > Bolt 1/2inch </desc> 
    <parts.item>  
</parts.category> 

*注意:<qty>移动 *注意:<partno>移动 *注意<nsn>不包括与排序的内容子元素

此外,某些实例包括作为子项嵌套在<desc>中的<uoc>元素。

​​

<uoc>实际上应该是<callout>后,和之前

<qty> 

使用XSLT样式表或XQuery脚本任何帮助将不胜感激,以及为什么选择在其他一种语言简短说明。我目前使用的氧气17 XML编辑器

回答

2

当输出的主要部分是一样的输入,XSLT通常符合该法案更好。总的原则是编写一个包含通用规则的样式表,以递归地复制元素,然后为要执行不同操作的元素添加规则。

在XSLT 3.0的一般规则是:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="3.0"> 
    <xsl:mode on-no-match="shallow-copy"/> 

    ... other code goes here ... 
</xsl:transform> 

虽然在早期版本中,它是:

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

    <xsl:template match="*"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"> 
    <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    ... other code goes here ... 
</xsl:transform> 

你的模板规则重新排序parts.item可以写成:

<xsl:template match="parts.item"> 
    <parts.item> 
    <xsl:copy-of select="callout"/> 
    <xsl:copy-of select="qty"/> 
    <xsl:copy-of select="mrs"/> 
    <nsn> 
     <fsc><xsl:value-of select="substring-before(nsn, '-')"/></fsc> 
     <niin><xsl:value-of select="nsn/@niin"/></niin> 
    </nsn> 
    <xsl:copy-of select="partno"/> 
    <xsl:copy-of select="cageno"/> 
    <xsl:copy-of select="name"/> 
    <xsl:copy-of select="desc"/> 
</parts.item> 

把这个在一起,下面的XSLT 2.0样式表:适用于以下源文件

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

    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="parts.item"> 
     <parts.item> 
      <xsl:copy-of select="callout"/> 
      <xsl:copy-of select="qty"/> 
      <xsl:copy-of select="mrs"/> 
      <nsn> 
       <fsc><xsl:value-of select="substring-before(nsn, '-')"/></fsc> 
       <niin><xsl:value-of select="nsn/@niin"/></niin> 
      </nsn> 
      <xsl:copy-of select="partno"/> 
      <xsl:copy-of select="cageno"/> 
      <xsl:copy-of select="name"/> 
      <xsl:copy-of select="desc"/> 
     </parts.item> 
    </xsl:template> 
</xsl:transform> 

<PartsDoc foo="" baa="" bar="" revno="" docno="" > 
    <PartsDocInfo> 
     <repairlvl level="shop" /> 
     <title id="123"> Foo Electrical Control Box </title> 
    </PartsDocInfo> 

    <Parts.Category> 

     <figure id="123" > 
     <title id="123"> Control Box Panels </title> 

     <subfig id="123"> 
        <graphic img="foo.jpg" /> 
     </subfig> 
       <!-- everything above is valid, the below portion is not --> 

       <parts.item> 
        <callout id="123" config="123" label="1" /> 
        <mrs service="shop" sc="" mc="" rec="" /> 
        <nsn niin="00-123-4567"> 4444-00-123-5467</nsn> 
        <cageno>12345</cageno> 
        <partno>12345</partno> 
        <name/> 
        <desc id="123" > Bolt 1/2inch </desc> 
        <qty>4</qty> 
       </parts.item> 
     </figure> 
    </Parts.Category> 
</PartsDoc> 

产生以下输出:

<?xml version="1.0" encoding="UTF-8"?> 
<PartsDoc foo="" baa="" bar="" revno="" docno=""> 
    <PartsDocInfo> 
     <repairlvl level="shop"/> 
     <title id="123"> Foo Electrical Control Box </title> 
    </PartsDocInfo> 
    <Parts.Category> 
     <figure id="123"> 
     <title id="123"> Control Box Panels </title> 
     <subfig id="123"> 
      <graphic img="foo.jpg"/> 
     </subfig> 
     <parts.item> 
      <callout id="123" config="123" label="1"/> 
      <qty>4</qty> 
      <mrs service="shop" sc="" mc="" rec=""/> 
      <nsn> 
       <fsc> 4444</fsc> 
       <niin>00-123-4567</niin> 
      </nsn> 
      <partno>12345</partno> 
      <cageno>12345</cageno> 
      <name/> 
      <desc id="123"> Bolt 1/2inch </desc> 
     </parts.item> 
     </figure> 
    </Parts.Category> 
</PartsDoc> 
+1

然后你做错了什么。在提供的XML和我的XSLT中有一些微不足道的拼写错误,但是在修复这些错误之后,它按预期工作,并添加了完整的详细信息。 –

+0

迈克尔如果我想保留parts.item元素中的任何属性,我该怎么做? 需要通过用@ *运算符进一步筛选来更改吗? – Akpan

+0

请不要以评论形式提出补充问题。 SO问题/答案格式不是为此设计的。如果您有补充问题,请将其作为一个新问题提出来,并从最初原则进行解释。 –