دمج اثنين من xpathdocents باستخدام xmlcompiledtransform
-
23-09-2019 - |
سؤال
لا يمكنني أن أكون أول شخص يقوم بذلك ، يبدو أنه سيكون من الممارسات الشائعة دمج مستندتين باستخدام XSLT. ومع ذلك ، لا يمكنني العثور على مثال واحد على in interweb.
لديّ اثنين من المستندات XML التي يتم استردادها كسلاسل من XML من SQL Server. أريد أن استخدام XslCompiledTransform
لدمج الوثيقين. وأنا أعلم ذلك XslCompiledTransform
يطفئ XSL document()
وظيفة بشكل افتراضي. لقد حولت ذلك باستخدام XsltSettings
عندما أقوم بإنشاء بلدي XslCompiledTransform
هدف.
ما أفهمه حول كيفية "إضافة" المستند الثاني إلى التحول هو استخدام XsltArgumentList
واستخدام AddParam()
الطريقة وإضافة ملف XPathNavigator
هدف:
XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
(string)e.UserState + "s", "http://www.myuri.com/tabledata",
dataXmlDoc.CreateNavigator()
);
ومع ذلك ، فإن أي محاولات للوصول إلى المستند الذي يتم إضافته يؤدي إلى خطأ أو لا يتم إرجاع أي شيء. - ج#:
XslCompiledTransform fieldToXhtmlTransform = new XslCompiledTransform(true);
try
{
UriBuilder xsltUri = new UriBuilder(
Request.Url.Scheme, Request.Url.Host,
Request.Url.Port, this.ResolveUrl("Transforms/address1.xslt")
);
XmlSecureResolver resolver = new XmlSecureResolver(
new XmlUrlResolver(), new PermissionSet(PermissionState.Unrestricted)
);
fieldToXhtmlTransform.Load(
xsltUri.ToString(), new XsltSettings(true, false), resolver
);
}
catch
{
//TODO: do something useful here.
}
XPathDocument fieldSchemaXmlDoc = null;
using (MemoryStream fieldMemoryStream = new MemoryStream(
Encoding.UTF8.GetBytes(e.Result.TableMetaDataXml)
))
{
fieldSchemaXmlDoc = new XPathDocument(fieldMemoryStream);
}
XPathDocument dataXmlDoc = null;
using (MemoryStream dataMemoryStream = new MemoryStream(
Encoding.UTF8.GetBytes(e.Result.DataXml)
))
{
dataXmlDoc = new XPathDocument(dataMemoryStream);
}
StringBuilder output = new StringBuilder();
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;
writerSettings.Encoding = Encoding.UTF8;
XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
(string)e.UserState + "s", "http://www.myuri.com/tabledata",
dataXmlDoc.CreateNavigator()
);
XmlWriter transformedDataWriter = XmlWriter.Create(output, writerSettings);
fieldToXhtmlTransform.Transform(
fieldSchemaXmlDoc, xsltArgs, transformedDataWriter
);
XSLT - الوصول فقط إلى المستند المضافة ، وليس المستند المحمل بالتحويل.
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:hlsschema="http://www.myuri.com/tableschema"
xmlns:hlsdata="http://www.myuri.com/tabledata"
exclude-result-prefixes="msxsl hlsschema hlsdata xsl"
>
<xsl:output method="html" indent="yes"/>
<p>
<xsl:template match="hlsdata:Address1s">
<xsl:for-each select="hlsdata:Address1">
<p>
<xsl:value-of select="hlsdata:dr_id"/>
</p>
</xsl:for-each>
</xsl:template>
</p>
</xsl:stylesheet>
XML
<hlsdata:Address1s
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hlsdata="http://www.myuri.com/tabledata"
>
<hlsdata:Address1>
<hlsdata:dr_id>12345678</hlsdata:dr_id>
</hlsdata:Address1>
</hlsdata:Address1s>
أعلم أنني أفتقد شيئًا واضحًا ، لكنه يتجاوز الإحباط. أعلم أنه يتم إضافة المستند كمعلمة ، لكن لا يمكنني العثور على مثال على كيفية الوصول إلى مستند تم تحميله كمعلمة.
أي مساعدة سيكون موضع تقدير كبير. ضع في اعتبارك أن الكود أعلاه هو عمل مستمر وبين مئات المحاولات لجعله يعمل ، لذا إذا كان هناك شيء يبدو غريبًا بعض الشيء ، فربما يكون ذلك بسبب محاولاته.
المحلول
تحتاج إلى تحديد معلمة في ورقة الأنماط الخاصة بك ثم استخدام هذه المعلمة. فيما يلي مثال بسيط ، يبدو أن ورقة الأنماط تبدو على النحو التالي:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:docs="http://example.com/2010/docs"
exclude-result-prefixes="docs"
>
<xsl:param name="docs:doc1" select="/.."/>
<xsl:template match="/">
<xsl:apply-templates select="$docs:doc1/node()"/>
</xsl:template>
<xsl:template match="root">
<ul>
<xsl:apply-templates/>
</ul>
</xsl:template>
<xsl:template match="foo">
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
</xsl:stylesheet>
يبدو رمز C# على النحو التالي:
string xml = "<root><foo>1</foo><foo>2</foo></root>";
XPathDocument doc = new XPathDocument(new StringReader(xml));
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load(@"..\..\XSLTFile1.xslt");
XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam("doc1", "http://example.com/2010/docs", doc.CreateNavigator());
proc.Transform(XmlReader.Create(new StringReader("<dummy/>")), xsltArgs, Console.Out);
هذا تطبيق وحدة تحكم يكتب إلى Simplicity إلى Console.out ولكن يمكنك بالطبع استخدام المخرجات الأخرى التي تسمح بها طريقة التحويل.
هذا المثال يكتب ثم يكتب <ul><li>1</li><li>2</li></ul>
لذلك تمت معالجة معلمة الإدخال.
لذلك يجب أن يوضح لك كيفية تمرير معلمة تعتبرها XSLcompileDTransform بمثابة مجموعة عقدة يمكنك معالجتها باستخدام XSLT.
أما بالنسبة لكتابة ورقة الأنماط التي تدمج مستندتين ، يرجى نشر عينتين إدخالين وعينة النتيجة المقابلة التي تريد إنشاءها إذا كان لديك مشاكل في كتابة XSLT.