我的问题是我有不同的XML文件具有相同的结构,我想提取这些输入文件的某些元素,并生成一个新的输出文档,其中包含的摘录。
所以,让我们弄清楚:-)(下面的示例链接)
input1.xml:
<?xml version="1.0" encoding="utf-16"?>
<msg:Msg xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:msg="http://some/msg/namespace/2.0">
<msg:preserve1>
<msg:preserve2>
<msg:preserve3>Preserve that</msg:preserve3>
</msg:preserve2>
<msg:Logon/>
</msg:preserve1>
<msg:Body>
<msg:Req>
<msg:Dta>
<ResponseRowset xmlns:msg="http://some/msg/namespace/1.1"
xmlns="http://defaultnamespace">
<ResponseRow>
<ArticleNo>123</ArticleNo>
<List>02</List>
<Flag>2</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>02</List>
<Flag>3</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>345</ArticleNo>
<List>03</List>
<Flag>3</Flag>
</ResponseRow>
</ResponseRowset>
</msg:Dta>
</msg:Req>
</msg:Body>
</msg:Msg>
input2.xml
<?xml version="1.0" encoding="utf-16"?>
<msg:Msg xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:msg="http://some/msg/namespace/2.0">
<msg:preserve1>
<msg:preserve2>
<msg:preserve3>Preserve that</msg:preserve3>
</msg:preserve2>
<msg:Logon/>
</msg:preserve1>
<msg:Body>
<msg:Req>
<msg:Dta>
<ResponseRowset xmlns:msg="http://some/msg/namespace/1.1"
xmlns="http://defaultnamespace">
<ResponseRow>
<ArticleNo>3423</ArticleNo>
<List>03</List>
<Flag>3</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>05</List>
<Flag>4</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>01</List>
<Flag>4</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>456</ArticleNo>
<List>03</List>
<Flag>3</Flag>
</ResponseRow>
</ResponseRowset>
</msg:Dta>
</msg:Req>
</msg:Body>
</msg:Msg>
现在,如果<ResponseRow>
标记包含指定的数字之一,我想将所有<ArticleNo>
标记及其子标记复制到新文件中。
让我们说我想拥有所有ResponseRow元素,其中ArticleNo是&#39; 234&#39;或者&#39; 456&#39;
我的预期结果应为
<?xml version="1.0" encoding="utf-16"?>
<msg:Msg xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:msg="http://some/msg/namespace/2.0">
<msg:preserve1>
<msg:preserve2>
<msg:preserve3>Preserve that</msg:preserve3>
</msg:preserve2>
<msg:Logon/>
</msg:preserve1>
<msg:Body>
<msg:Req>
<msg:Dta>
<ResponseRowset xmlns:msg="http://some/msg/namespace/1.1" xmlns="http://defaultnamespace">
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>02</List>
<Flag>3</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>05</List>
<Flag>4</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>456</ArticleNo>
<List>03</List>
<Flag>3</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>234</ArticleNo>
<List>05</List>
<Flag>4</Flag>
</ResponseRow>
<ResponseRow>
<ArticleNo>456</ArticleNo>
<List>03</List>
<Flag>3</Flag>
</ResponseRow>
</ResponseRowset>
</msg:Dta>
</msg:Req>
</msg:Body>
</msg:Msg>
如果我在一个文件中包含所有内容,则使用以下xsl文件:
<xsl:stylesheet version="2.0"
xmlns:msg="http://some/msg/namespace/2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="utf-16"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*" xpath-default-namespace="http://defaultnamespace">
<xsl:copy>
<xsl:apply-templates select="node() except ResponseRow[ArticleNo!='234' and ArticleNo!='456']"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但我无法使用两个或更多输入文件。这是&#34; one-file&#34;的链接。例如:http://xsltransform.net/3NzcBsK/33
我不喜欢的是像 ResponseRow [ArticleNo!=&#39; 234&#39;和ArticleNo!=&#39; 456&#39;] 因为我会列出10个不同的文章编号,但这不是我的主要关注点。
请注意,名称空间看起来很奇怪,但由于文件是由某个供应商生成的,因此我不会对此产生影响
如果你可以帮我解决这个问题会很好。
答案 0 :(得分:1)
*
上的匹配对我来说很奇怪,对于第二个文件和那些文章编号,我会定义一个全局参数
<xsl:param name="articles-to-copy" as="xs:string*" select="'234', '456'"/>
然后匹配
<xsl:template match="ResponseRowset" xpath-default-namespace="http://defaultnamespace">
<xsl:copy>
<xsl:apply-templates select="(ResponseRow , doc('file2.xml')//ResponseRow)[ArticleNo = $articles-to-copy]"/>
</xsl:copy>
</xsl:template>
当然伴随着身份转换模板
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:0)
非常感谢Martin Honnen指出要走的路,唯一不起作用的是参数值。
再次感谢你,我的最终解决方案是:
<xsl:param name="articles-to-copy" select="('234', '456')" />
<xsl:variable name="pricelist01" select="document('input1.xml')"/>
<xsl:variable name="pricelist02" select="document('input2.xml')"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ResponseRowset" xpath-default-namespace="http://defaultnamespace">
<xsl:copy>
<xsl:apply-templates select="(ResponseRow, $pricelist01//ResponseRow, $pricelist02//ResponseRow)[StockCode=$articles-to-copy]"/>
</xsl:copy>
</xsl:template>
这是在另外两个文件中进行查找。我做的唯一更改是从标记中删除 as =“xs:string”。看起来真的很不错: - )