我有以下XML:
<?xml version="1.0" encoding="utf-8"?>
<string>
<Table>
<Rows>
<Row Id="0">
<Column Name="INS_NAME" XPath="Ins.Name">Jane</Column>
<Column Name="INS_LASTNAME" XPath="Ins.LastName">Smith</Column>
</Row>
<Row Id="1">
<Column Name="INS_NAME" XPath="Ins.Name">Joe</Column>
<Column Name="INS_LASTNAME" XPath="Ins.LastName">Miller</Column>
</Row>
<Row Id="2">
<Column Name="INS_NAME" XPath="Ins.Name">George</Column>
<Column Name="INS_LASTNAME" XPath="Ins.LastName">Ramsey</Column>
</Row>
</Rows>
</Table>
</string>
我希望使用单个 XSLT将其转换为此XML:
<?xml version="1.0" encoding="utf-8"?>
<Customers>
<Customer><Name>Jane</Name><LastName>Smith</LastName></Customer>
<Customer><Name>Joe</Name><LastName>Miller</LastName></Customer>
<Customer><Name>George</Name><LastName>Ramsey</LastName></Customer>
</Customers>
我可以使用两种不同的XSLT来实现:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="/" disable-output-escaping="yes" />
</xsl:template>
</xsl:stylesheet>
然后:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Customers>
<xsl:for-each select="Table/Rows/Row">
<Customer>
<Name><xsl:value-of select="Column[@Name='INS_NAME']" /></Name>
<LastName><xsl:value-of select="Column[@Name='INS_LASTNAME']" /></LastName>
</Customer>
</xsl:for-each>
</Customers>
</xsl:template>
</xsl:stylesheet>
我一直在阅读关于多相变换但我似乎无法得到它。我尝试在变量中保存第一个XSLT,但保存到变量时似乎disable-output-escaping="yes"
不起作用。
有人可以帮忙吗?
谢谢。
新信息(编辑)
我现在正在以这种方式翻译字符串:
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="stringXml">
<?xml version="1.0" encoding="utf-8"?>
<xsl:value-of select="translate(translate(/,'>','>'),'<','<')" />
</xsl:variable>
...
如何对存储在stringXML中的结果XML进行转换?
最终解决方案(编辑)
<msxml:script implements-prefix="myLib" language="C#">
<msxml:assembly name="System.Web"/>
<msxml:using namespace="System.Web"/>
<![CDATA[
public System.Xml.XPath.XPathNodeIterator convertText(string text)
{
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(text);
return doc.CreateNavigator().Select("/");
}
]]>
</msxml:script>
答案 0 :(得分:2)
似乎disable-output-escaping =“yes”在保存到a时不起作用 变量
你的观察是正确的。
DOE仅影响转换(最终)结果的序列化,不适用于中间树。
以下是 W3C XSLT 1.0 specification 明确说明的内容:
“ XSLT处理器只能禁用输出转义 控制结果树的输出方式。这可能并不总是如此 案件。例如,结果树可以用作源树 另一个XSLT转换而不是输出。“
同样的否定答案适用于尝试使用变量,该变量的值是一个字符串,包含XML文档的文本表示。
答案 1 :(得分:1)
我遇到类似的情况,我需要在实际的XML中解析转义的XML。我会发布我的解决方案,以帮助其他人。另请注意,我也在使用Saxon-PE解析器。
在我的情况下,我有一个原始XML,它包含子节点中的转义XML。我需要在转义的XML的 RootNode 中获取内部XML。
源XML:
<?xml version="1.0" encoding="utf-8"?>
<MyTestXml>
<SomeXmlStuff>
<Text1>Hello</Text1>
<Text2>World</Text2>
</SomeXmlStuff>
<SomeEscapedXml><RootNode><FirstNode>Hello</FirstNode><SecondNode>World</SecondNode><ThirdNode>Again</ThirdNode></RootNode></SomeEscapedXml>
</MyTestXml>
当您转义XML时,它看起来像这样:
<RootNode>
<FirstNode>Hello</FirstNode>
<SecondNode>World</SecondNode>
<ThirdNode>Again</ThirdNode>
</RootNode>
在源XML上应用以下XSLT转换:
<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
exclude-result-prefixes="xsl saxon">
<xsl:template match="/">
<MyOutput>
<xsl:call-template name="GetRootNodeInnerXml">
<xsl:with-param name="escapedXml" select="MyTestXml/SomeEscapedXml" />
</xsl:call-template>
</MyOutput>
</xsl:template>
<xsl:template name="GetRootNodeInnerXml">
<xsl:param name="escapedXml" required="yes" />
<xsl:copy-of select="saxon:parse($escapedXml)/RootNode/node()"/>
<!-- You can also use this line below if you're not using saxon parser. Just make sure your parser supports XSL 3.0 -->
<!--
<xsl:copy-of select="fn:parse-xml($escapedXml)/RootNode/node()" xmlns:fn="http://www.w3.org/2005/xpath-functions"/>
-->
</xsl:template>
</xsl:stylesheet>
这为您提供以下输出:
<?xml version='1.0' ?>
<MyOutput>
<FirstNode>Hello</FirstNode>
<SecondNode>World</SecondNode>
<ThirdNode>Again</ThirdNode>
</MyOutput>